/*************************************************************************************************************************************/ /* */ /* P R E - P R O C E S S E U R ' cpp ' : */ /* */ /* */ /* Author of '$xcp/cpp$D/beau_cpp$c' : */ /* */ /* Unknown... */ /* */ /* */ /* Version amelioree de '$xcp/cpp$D/beau_cpp$c' par : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 19840320120000). */ /* */ /*************************************************************************************************************************************/ #define ALLOCATION_STATIQUE /* La possibilite eventuelle de passer a l'allocation dynamique des grandes structures */ /* a ete introduite le 20210228093631, le programme 'v $xtc/chaines.02$c' validant le */ /* principe de cette transformation... */ /* */ /* Malheureusement, a la date du 20210228102007, l'allocation dynamique provoque lors de */ /* 'v $xcc/cpp$Z .CA..fichier_Verif1....xcp.cpp.X' (les tests ayant ete faits sur le */ /* programme 'v $xci/neutre$K') : */ /* */ /* Segmentation fault */ /* */ /* dans la fonction 'yyparse(...)' generee par '$YACC' via 'v $xcpp/beau_cpy$Y', la */ /* definition de 'yyparse(...)' se trouvant dans le fichier temporaire '$xcpp/y.tab$c' */ /* (genere par 'v $xcpp/GENERE$Z .YACC......FiChIeRT_yacc') via 'YYPARSE_DECL(...)'. */ /* */ /* Les experiences faites alors montrent que cela provient de la premiere ligne : */ /* */ /* #if (PRECISION_DU_Int==SIMPLE_PRECISION) */ /* */ /* rencontree dans le fichier temporaires '$fichier_Verif1' et qui correspond en fait a la */ /* premiere ligne contenant une erreur (l'un au moins des deux symboles n'est pas defini). */ /* L'instruction en cause est l'appel : */ /* */ /* fprintf(stderr,s,x,y); */ /* */ /* fait a l'interieur de la fonction 'pperror(s,x,y)'... */ /* */ /* En fait, les experiences du 20210301092859 montrent que le probleme n'etait pas la, */ /* mais que le "Segmentation fault" se produisait dans 'pperror(s,x,y)'. Mais en fait le */ /* probleme n'etait pas la non plus, mais dans le 'malloc(dLbuffer)' execute au tout */ /* debut du 'main(...)'. En fait, on trouve que : */ /* */ /* Lbuffer >= 1929193 ==> Segmentation fault */ /* */ /* alors que : */ /* */ /* Lbuffer < 1929193 */ /* */ /* fonctionne parfaitement. Alors, pourquoi ne peut-on pas allouer "proprement" plus */ /* de memoire ? */ /* */ /* En fait, le probleme a ete resolu le 20210301160823 : il y avait effectivement une erreur */ /* de programmation (remontant a la nuit des temps et dont je ne suis pas responsable) dans */ /* 'v $xcpp/beau_yylex$c'. En effet celui-ci utilisait la fonction 'pperror(...)' qui */ /* demande trois arguments, alors que deux seulement etaient fournis. La fonction */ /* 'yypperror(...)' a deux arguments a donc ete introduite. Mais cela n'a pas suffit : */ /* le 20210228102007 il a fallu typer son argument 'x' (dont le type est connu...). */ /* */ /* */ /* Le 20210301174813, je note avec angoisse que 'BUFSIZ' intervient explicitement a de */ /* tres nombreux endroits et qu'ainsi n'allouer dynamiquement que 'buffer' est peut-etre */ /* tres insuffisant. Et evidemment, il en est de meme avec 'SBSIZE'... */ /* */ /* A compter du 20210302092914 ce qui precede a ete corrige et l'allocation dynamique */ /* semble fonctionner de facon strictement identique a l'allocation statique... */ /* */ /* L'activation de l'allocation dynamique se fait donc en introduisant un : */ /* */ /* #undef ALLOCATION_STATIQUE */ /* */ /* ci-dessus, apres le '#define' ou ici-meme... */ /* */ /* On notera, malgre tout, qu'etant donne que les zones allouees dynamiquement sont */ /* nettoyees avant usage, l'allocation dynamique est penalisante au niveau performance... */ /* Le 20210304102609 j'inhibe ce nettoyage qui semble inutile... */ #include "stdio.h" #include "ctype.h" #ifdef ALLOCATION_STATIQUE #else ALLOCATION_STATIQUE # include "stdlib.h" extern void *malloc(); #endif ALLOCATION_STATIQUE extern char *getenv(); #define REGISTER \ /* Introduit le 20071122111714 en vue de supprimer 'register' et supprime le 20071122112104 */ \ /* alors qu'avant cette date il y avait ici : */ \ /* */ \ /* #define REGISTER register */ \ /* */ #define CHAR char #define cCHAR(caractere) caractere #define fCHAR(chaine) chaine #ifdef SYSTEME_APC_LinuxDebian_GCC # undef CHAR # define CHAR unsigned char # undef cCHAR # define cCHAR(caractere) ((CHAR)caractere) /* Une nouvelle preuve de l'existence de Dieu : en l'absence de cela, les fichiers */ /* resultants contenaient plein de caracteres "exotiques". J'essaye cela un peu au */ /* hasard et cela marche... */ #else SYSTEME_APC_LinuxDebian_GCC #endif SYSTEME_APC_LinuxDebian_GCC #ifdef SYSTEME_APC_LinuxMandrake_GCC # undef CHAR # define CHAR unsigned char # undef cCHAR # define cCHAR(caractere) ((CHAR)caractere) /* Une nouvelle preuve de l'existence de Dieu : en l'absence de cela, les fichiers */ /* resultants contenaient plein de caracteres "exotiques". J'essaye cela un peu au */ /* hasard et cela marche... */ #else SYSTEME_APC_LinuxMandrake_GCC #endif SYSTEME_APC_LinuxMandrake_GCC #ifdef SYSTEME_APC_LinuxRedHat_GCC # undef CHAR # define CHAR unsigned char # undef cCHAR # define cCHAR(caractere) ((CHAR)caractere) /* Une nouvelle preuve de l'existence de Dieu : en l'absence de cela, les fichiers */ /* resultants contenaient plein de caracteres "exotiques". J'essaye cela un peu au */ /* hasard et cela marche... */ #else SYSTEME_APC_LinuxRedHat_GCC #endif SYSTEME_APC_LinuxRedHat_GCC #ifdef SYSTEME_APC_LinuxUbuntu_GCC /* Introduit le 20071122104248... */ #else SYSTEME_APC_LinuxUbuntu_GCC #endif SYSTEME_APC_LinuxUbuntu_GCC #ifdef SYSTEME_APC_LinuxUbuntu_ICC /* Introduit le 20071130113030... */ #else SYSTEME_APC_LinuxUbuntu_ICC #endif SYSTEME_APC_LinuxUbuntu_ICC #ifdef SYSTEME_APC_LinuxUlmint_GCC /* Introduit le 20160810114404... */ #else SYSTEME_APC_LinuxUlmint_GCC #endif SYSTEME_APC_LinuxUlmint_GCC #ifdef SYSTEME_APC_LinuxUlmint_ICC /* Introduit le 20160922155324... */ #else SYSTEME_APC_LinuxUlmint_ICC #endif SYSTEME_APC_LinuxUlmint_ICC #ifdef SYSTEME_FX2800_CONCENTRIX_SCC # undef CHAR # define CHAR unsigned char # undef cCHAR # define cCHAR(caractere) ((CHAR)caractere) #else SYSTEME_FX2800_CONCENTRIX_SCC #endif SYSTEME_FX2800_CONCENTRIX_SCC #ifdef SYSTEME_HP705_HPUX_CC # undef CHAR # define CHAR unsigned char # undef cCHAR # define cCHAR(caractere) ((CHAR)caractere) #else SYSTEME_HP705_HPUX_CC #endif SYSTEME_HP705_HPUX_CC #ifdef SYSTEME_HP710_HPUX_CC # undef CHAR # define CHAR unsigned char # undef cCHAR # define cCHAR(caractere) ((CHAR)caractere) #else SYSTEME_HP710_HPUX_CC #endif SYSTEME_HP710_HPUX_CC #ifdef SYSTEME_HP720_HPUX_CC # undef CHAR # define CHAR unsigned char # undef cCHAR # define cCHAR(caractere) ((CHAR)caractere) #else SYSTEME_HP720_HPUX_CC #endif SYSTEME_HP720_HPUX_CC #ifdef SYSTEME_HP750_HPUX_CC # undef CHAR # define CHAR unsigned char # undef cCHAR # define cCHAR(caractere) ((CHAR)caractere) #else SYSTEME_HP750_HPUX_CC #endif SYSTEME_HP750_HPUX_CC #ifdef SYSTEME_NWS3000_NEWSOS_2CC # undef CHAR # define CHAR unsigned char # undef fCHAR(chaine) # define fCHAR(chaine) fchar(chaine) CHAR *fchar(chaine) CHAR *chaine; { return(chaine); } #else SYSTEME_NWS3000_NEWSOS_2CC #endif SYSTEME_NWS3000_NEWSOS_2CC #ifdef SYSTEME_VAX9000_ULTRIX_GCC # undef CHAR # define CHAR unsigned char # undef cCHAR # define cCHAR(caractere) ((CHAR)caractere) # undef fCHAR(chaine) # define fCHAR(chaine) fchar(chaine) CHAR *fchar(chaine) CHAR *chaine; { return(chaine); } #else SYSTEME_VAX9000_ULTRIX_GCC #endif SYSTEME_VAX9000_ULTRIX_GCC #define STATIC #define STDIN 0 #define STDOUT 1 #define STDERR 2 #define CLASSCODE 27 /* Exit status if #class seen. */ #define RETURN_0 0 #define RETURN_2 2 #define RETURN_8 8 #define Cnull '\0' #define READ "r" #define WRITE "w" #define SALT \ '#' CHAR var_SALT=SALT; /* Permet de changer le caractere d'introduction des commandes a 'cpp' (John F. COLONNA). */ #define CONCATENEUR \ Cnull CHAR var_CONC=CONCATENEUR; /* Permet de changer le caractere de concatenation substitue a 'var_SALT' (John F. COLONNA). */ /* Initialement et implicitement, il est nul, ce qui rend ce dispositif ineffectif tant */ /* qu'il n'est pas active par l'argument "-k". */ #define EXTENSEUR \ Cnull CHAR var_EXTE=EXTENSEUR; /* Permet de changer le caractere 'var_SALT' d'introduction des directives non reconnues */ /* (par exemple 'pragma' ou 'ident'). Initialement et implicitement, il est nul, ce qui rend */ /* ce dispositif ineffectif tant qu'il n'est pas active par l'argument "-e". */ int var_warning=0; /* Permet d'inhiber les warnings des macros f(...) n'ayant pas leurs arguments d'appel. */ int compteur__A__=0; int compteur__B__=0; /* Compteur qui donnera sa valeur a la variable intrinseque '__PLUS1__A__'/'__MOINS1__A__'. */ /* */ /* Un deuxieme compteur ('B') a ete introduit le 20190831104916 et ce afin de permettre */ /* 'v $xig/fonct$vv$DEF 20190831122149'... */ #define SUITE '\\' #undef BUFSIZ #define BUFSIZ (1024*4096) /* Pour John F. COLONNA. Modifications : */ /* */ /* 128 --> 1024 20041118151222 pour 'v $xrs/project2D.11$K'. */ /* */ /* 1024 --> 256 20041120143010 (suffisant en fait...). */ /* */ /* 256 --> 512 20100319144759 pour 'v $xbmcf/conformes$K' avec */ /* 'v $xil/defi_K1$vv$DEF 20100317' */ /* et $?PRE_GENERATION == $NEXIST. */ /* */ /* 512 --> 1024 20210207113507 pour 'v $xbmcf/iterations$K' et */ /* des 'DEFV(Common,GENERE__Fonct's */ /* tres longs...). */ /* */ /* La variable 'BUFSIZ' intervient dans les messages : */ /* */ /* "actuals too long" via 'BUFSIZ', */ /* "too much defining" via 'SBSIZE-BUFSIZ'. */ /* */ #ifdef SYSTEME_DECALPHA340_OSF1_CC # undef BUFSIZ # define BUFSIZ (100*4096) \ /* Ceci afin d'eviter les messages suivants : */ \ /* */ \ /* as1: Error: beau_cpp.c, line 1518: large stack frames not yet supported */ \ /* as1: Error: beau_cpp.c, line 2347: large stack frames not yet supported */ \ /* as1: Error: beau_cpp.c, line 2399: large stack frames not yet supported */ \ /* as1: Error: beau_cpp.c, line 3144: large stack frames not yet supported */ \ /* */ \ /* D'autre part, la valeur ne peut exceder apparemment '100*4096', car sinon, on se retrouve */ \ /* a l'entree de 'dodef(...)' avec le message : */ \ /* */ \ /* Segmentation fault (core dumped) */ \ /* */ \ /* certainement dans l'allocation de 'formtxt[BUFSIZ]'. */ #else SYSTEME_DECALPHA340_OSF1_CC #endif SYSTEME_DECALPHA340_OSF1_CC #ifdef SYSTEME_DECALPHA350_OSF1_CC # undef BUFSIZ # define BUFSIZ (100*4096) \ /* Ceci afin d'eviter les messages suivants : */ \ /* */ \ /* as1: Error: beau_cpp.c, line 1518: large stack frames not yet supported */ \ /* as1: Error: beau_cpp.c, line 2347: large stack frames not yet supported */ \ /* as1: Error: beau_cpp.c, line 2399: large stack frames not yet supported */ \ /* as1: Error: beau_cpp.c, line 3144: large stack frames not yet supported */ \ /* */ \ /* D'autre part, la valeur ne peut exceder apparemment '100*4096', car sinon, on se retrouve */ \ /* a l'entree de 'dodef(...)' avec le message : */ \ /* */ \ /* Segmentation fault (core dumped) */ \ /* */ \ /* certainement dans l'allocation de 'formtxt[BUFSIZ]'. */ #else SYSTEME_DECALPHA350_OSF1_CC #endif SYSTEME_DECALPHA350_OSF1_CC CHAR *pbeg,*pbuf,*pend; CHAR *outp,*inp; CHAR *newp; CHAR cinit; /* Some code depends on whether characters are sign or zero extended. */ #define COFF 0 #define ALFSIZ 256 /* Alphabet size. */ CHAR macbit[ALFSIZ+11]; CHAR toktyp[ALFSIZ]; #define BLANK 1 #define IDENT 2 #define NUMBR 3 #include "beau_cpp.I" #define scw1 1 #define scw2 0 /* A superimposed code is used to reduce the number of calls to the */ /* symbol table lookup routine. (if the kth character of an identifier */ /* is 'a' and there are no macro names whose kth character is 'a' */ /* then the identifier cannot be a macro name, hence there is no need */ /* to look in the symbol table.) 'scw1' enables the test based on */ /* single characters and their position in the identifier. 'scw2' */ /* enables the test based on adjacent pairs of characters and their */ /* position in the identifier. scw1 typically costs 1 indexed fetch, */ /* an AND, and a jump per character of identifier, until the identifier */ /* is known as a non-macro name or until the end of the identifier. */ /* scw1 is inexpensive. scw2 typically costs 4 indexed fetches, */ /* an add, an AND, and a jump per character of identifier, but it is also */ /* slightly more effective at reducing symbol table searches. */ /* scw2 usually costs too much because the symbol table search is */ /* usually short; but if symbol table search should become expensive, */ /* the code is here. */ /* using both scw1 and scw2 is of dubious value. */ #if scw2 CHAR t21[ALFSIZ],t22[ALFSIZ],t23[ALFSIZ+NCPS]; #else scw2 #endif scw2 #if scw1 #define b0 1 #define b1 2 #define b2 4 #define b3 8 #define b4 16 #define b5 32 #define b6 64 #define b7 128 #else scw1 #endif scw1 #define IB 1 #define SB 2 #define NB 4 #define CB 8 #define QB 16 #define WB 32 #define AB 64 /* L'indicateur 'AB' a ete introduit le 20190120101149 pour 'ifonct(...)'. On notera le */ /* 'A' de 'AB' pour "procedures avec Arguments"... */ CHAR fastab[ALFSIZ]; /* Definitions des bits de 'fastab' suivant les codes caracteres 'c' : */ /* */ /* */ /* c = _ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 */ /* c = _ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$ */ /* (suivant l'option "-A") */ /* fastab[c] = IB | NB | SB */ /* */ /* c = _ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789(,) */ /* fastab[c] = AB */ /* */ /* c = 0123456789. */ /* fastab[c] = NB | SB */ /* */ /* c = N"'/\ (ou 'N' represente "\n") */ /* fastab[c] = SB */ /* */ /* c = N"'\ (ou 'N' represente "\n") */ /* fastab[c] = QB */ /* */ /* c = N* (ou 'N' represente "\n") */ /* fastab[c] = CB */ /* */ /* fastab[warnc] = WB | SB */ /* fastab[Cnull] = CB | QB | SB | WB */ /* */ CHAR slotab[ALFSIZ]; CHAR *ptrtab; #define isslo ( ptrtab == ( slotab + COFF ) ) #define isid(a) ( ( fastab + COFF )[a] & IB ) #define isspc(a) ( ptrtab[a] & SB ) #define isnum(a) ( ( fastab + COFF )[a] & NB ) #define iscom(a) ( ( fastab + COFF )[a] & CB ) #define isquo(a) ( ( fastab + COFF )[a] & QB ) #define iswarn(a) ( ( fastab + COFF )[a] & WB ) #define ifonct(a) ( ( fastab + COFF )[a] & AB ) /* La procedure 'ifonct(...)' a ete introduite le 20190120101149 afin de permettre */ /* d'utiliser l'option "-D" avec des procedures avec "Arguments" et par exemple : */ /* */ /* -D"fonction(a,b)=(a+b)" */ /* */ #define eob(a) ( ( a ) >= pend ) #define bob(a) ( pbeg >= ( a ) ) #define gLbuf(l) (NCPS+l+l+NCPS) #define Lbuffer gLbuf(BUFSIZ) #ifdef ALLOCATION_STATIQUE CHAR buffer[Lbuffer]; #define eBUFSIZ BUFSIZ #else ALLOCATION_STATIQUE size_t dBUFSIZ=BUFSIZ; #define eBUFSIZ dBUFSIZ #define dLbuffer gLbuf(dBUFSIZ) CHAR *buffer; #endif ALLOCATION_STATIQUE #define SBSIZE 50000000 /* Pour John F. COLONNA. Modifications : */ /* */ /* 4000000 --> 5000000 19990120145144 pour 'v $xrs/minimale.11$K' */ /* */ /* 5000000 --> 6000000 20010531091959 pour 'v $xrs/CalabiYau.21$K' */ /* */ /* 6000000 --> 40000000 20041118151222 pour 'v $xrs/project2D.11$K' */ /* */ /* 40000000 --> 10000000 20041118151222 (suffisant en fait...) */ /* */ /* 10000000 --> 20000000 20041118151222 pour 'v $xrs/CalabiYau.21$K' */ /* */ /* 20000000 --> 40000000 20100319144759 pour 'v $xbmcf/conformes$K' avec */ /* 'v $xil/defi_K1$vv$DEF 20100317' */ /* et $?PRE_GENERATION == $NEXIST. */ /* */ /* 40000000 --> 50000000 20210226171423 pour 'v $xrs/CalabiYau.21$K' */ /* suite a la modification */ /* 'v $Fincludes_bas 202102260754'. */ /* */ /* La variable 'SBSIZE' intervient dans les messages : */ /* */ /* "no space" via 'SBSIZE', */ /* "too much defining" via 'SBSIZE-BUFSIZ'. */ /* */ #ifdef ALLOCATION_STATIQUE CHAR sbf[SBSIZE]; #define eSBSIZE SBSIZE CHAR *savch = sbf; #else ALLOCATION_STATIQUE size_t dSBSIZE=SBSIZE; CHAR *sbf; #define eSBSIZE dSBSIZE CHAR *savch; #endif ALLOCATION_STATIQUE #define DROP cCHAR('\376') /* Special character not legal ASCII or EBCDIC. */ #define WARN DROP #define SAME 0 #define MAXINC 32 /* Nombre maximum d'includes imbriques. */ #define MAXFRE 14 /* Max buffers of macro pushback. */ #define MAXFRM 255 /* Max number of formals/actuals to a macro (passe de 63 a 127 le 20071026115044 pour */ /* 'v $ximd/operator.1$FON HORNER_3_03', puis de 127 a 255 le 20071028120654 pour */ /* 'v $ximd/operator.1$FON HORNER_7_01'...). */ static CHAR warnc = WARN; int mactop,fretop; CHAR *instack[MAXFRE],*bufstack[MAXFRE],*endbuf[MAXFRE]; int plvl; /* Parenthesis level during scan for macro actuals. */ int maclin; /* Line number of macro call requiring actuals. */ CHAR *macfil; /* File name of macro call requiring actuals. */ CHAR *macnam; /* Name of macro requiring actuals. */ int maclvl; /* # calls since last decrease in nesting level. */ CHAR *macforw; /* Pointer which must be exceeded to decrease nesting level. */ int macdam; /* Offset to macforw due to buffer shifting. */ STATIC int inctop[MAXINC]; STATIC CHAR *fnames[MAXINC]; STATIC CHAR *dirnams[MAXINC]; /* Actual directory of #include files. */ #define MESSAGE_0 0 #define MESSAGE_1 1 #define MESSAGE_2 2 #define MESSAGE_3 3 #define MESSAGE_4 4 #define MESSAGE_5 5 STATIC int message=MESSAGE_0; /* ATTENTION, avant le 1995032900, cette variable n'etait pas initialisee explicitement. */ /* */ /* Signification des differents codes : */ /* */ /* 0 include, */ /* 1 message, */ /* 2 Einclude, */ /* 3 system, (introduit le 20161209092257) */ /* 4 Winclude, (introduit le 20161213144856) */ /* 5 warning, (introduit le 20210903175906) */ /* */ /* -1 autres directives. */ /* */ STATIC FILE *fins[MAXINC]; STATIC int lineno[MAXINC]; STATIC CHAR *dirs[MAXINC]; /* -I and <> directories. */ CHAR *copy(),*subst(),*trmdir(),*strchr(); #ifdef SYSTEME_APC_LinuxDebian_GCC # define fin_stdin__fout_stdout #else SYSTEME_APC_LinuxDebian_GCC #endif SYSTEME_APC_LinuxDebian_GCC #ifdef SYSTEME_APC_LinuxMandrake_GCC # define fin_stdin__fout_stdout #else SYSTEME_APC_LinuxMandrake_GCC #endif SYSTEME_APC_LinuxMandrake_GCC #ifdef SYSTEME_APC_LinuxRedHat_GCC # define fin_stdin__fout_stdout #else SYSTEME_APC_LinuxRedHat_GCC #endif SYSTEME_APC_LinuxRedHat_GCC #ifdef SYSTEME_APC_LinuxUbuntu_GCC # define fin_stdin__fout_stdout #else SYSTEME_APC_LinuxUbuntu_GCC #endif SYSTEME_APC_LinuxUbuntu_GCC #ifdef SYSTEME_APC_LinuxUbuntu_ICC # define fin_stdin__fout_stdout #else SYSTEME_APC_LinuxUbuntu_ICC #endif SYSTEME_APC_LinuxUbuntu_ICC #ifdef SYSTEME_APC_LinuxUlmint_GCC # define fin_stdin__fout_stdout #else SYSTEME_APC_LinuxUlmint_GCC #endif SYSTEME_APC_LinuxUlmint_GCC #ifdef SYSTEME_APC_LinuxUlmint_ICC # define fin_stdin__fout_stdout #else SYSTEME_APC_LinuxUlmint_ICC #endif SYSTEME_APC_LinuxUlmint_ICC #ifdef fin_stdin__fout_stdout # define fin stdin # define fout stdout # undef fin_stdin__fout_stdout #else fin_stdin__fout_stdout STATIC FILE *fin; STATIC FILE *fout; #endif fin_stdin__fout_stdout STATIC int nd = 1; STATIC int uflag=0; /* Ne pas editer (si egal 1) les messages d'erreur du type : */ /* */ /* Error : ...: undef symbol ... in preprocessor if */ /* */ STATIC int pflag=0; /* Don't put out lines "# 12 foo.c" */ /* ATTENTION, avant le 1995032900, cette variable n'etait pas initialisee explicitement. */ STATIC int passcom=0; /* Don't delete comments. */ /* ATTENTION, avant le 1995032900, cette variable n'etait pas initialisee explicitement. */ STATIC int rflag=0; /* Allow macro recursion. */ /* ATTENTION, avant le 1995032900, cette variable n'etait pas initialisee explicitement. */ #define IFNO 0 STATIC int ifno=IFNO; /* Numero (a partir de 0 pour le fichier de base) du fichier inclu en cours. */ /* ATTENTION, avant le 1995032900, cette variable n'etait pas initialisee explicitement. */ /* La constante 'IFNO' a ete introduite le 20000831150255... */ #define NPREDEF 128 /* ATTENTION, il y avait avant : */ /* */ /* #define NPREDEF 20 */ /* */ /* mais les tests "trop de "-D" et "trop de -U" ne marchent pas, ce qui a ete mis en */ /* evidence dans '$xcc/cpp$Z' lorsque le nombre de defines par "-D" a atteint 21 lors du */ /* remplacement de l'option 'inclure_DEFINIT_cK_DEF' par le couple 'inclure_DEFINIT_c_DEF' */ /* et 'inclure_DEFINIT_K_DEF'... */ /* */ /* Le 20200412143912, la valeur : */ /* */ /* #define NPREDEF 64 */ /* */ /* a du etre augmentee suite a 'v $xcc/cpp$Z 20200412103853', la definition '$DEF_UNDEF' */ /* ayant ete allongee et contenait alors 65 options "-D"s sur '$LACT19' a cette date (on */ /* notera au passage que sur '$LACT1A' il y avait moins de 65 options "-D"s (en fait il y */ /* avait une de moins : celle de 'v $xccp/cpp$Y D..xREFERENCE'...). */ STATIC CHAR *prespc[NPREDEF]; STATIC CHAR **predef = prespc; STATIC CHAR *punspc[NPREDEF]; STATIC CHAR **prund = punspc; STATIC int exfail=0; /* ATTENTION, avant le 1995032900, cette variable n'etait pas initialisee explicitement. */ struct symtab { CHAR *name; CHAR *value; } *lastsym,*lookup(),*slookup(); struct symtab *stsym(); #define symsiz 20000 /* Pour JF. COLONNA (avant 2000). */ #define LINEFORM "# %d \"%s\" %d\n" #define ERRFORM "*%c* \"%s\",line " STATIC int ShowIncludes=0; /* 0=ne pas editer les '#define' a la fin, 1=editer les '#define'. */ STATIC int Showdefines=0; /* 0=ne pas lister les '#define' a la fin, 1=lister les '#define'. */ STATIC struct symtab stab[symsiz]; /* Table de tous les symboles (y compris les mots-clefs, tel '#define') definis. Cette */ /* table est accedee par une methode de type "hash-coding"... */ STATIC int DefDirectives=0; /* Introduit le 20090913183034 afin de savoir si l'on est en train de definir l'une des */ /* directives (au debut...) ou s'il s'agit d'un symbole... */ STATIC struct symtab *defloc; STATIC struct symtab *redefloc; STATIC struct symtab *defmloc; STATIC struct symtab *tdefloc; STATIC struct symtab *Defloc; STATIC struct symtab *udfloc; STATIC struct symtab *Udfloc; STATIC struct symtab *nodefloc; STATIC struct symtab *notdefloc; STATIC struct symtab *nydefloc; STATIC struct symtab *incloc; STATIC struct symtab *Eincloc; STATIC struct symtab *Wincloc; STATIC struct symtab *mesloc; STATIC struct symtab *warloc; STATIC struct symtab *sysloc; STATIC struct symtab *ifloc; STATIC struct symtab *elsloc; STATIC struct symtab *elsiloc; STATIC struct symtab *Aifloc; STATIC struct symtab *eifloc; STATIC struct symtab *Eifloc; STATIC struct symtab *ifdloc; STATIC struct symtab *elsdloc; STATIC struct symtab *Aifdloc; STATIC struct symtab *eifdloc; STATIC struct symtab *Eifdloc; STATIC struct symtab *ifnloc; STATIC struct symtab *elsndloc; STATIC struct symtab *Aifndloc; STATIC struct symtab *eifndloc; STATIC struct symtab *Eifndloc; STATIC struct symtab *ysysloc; STATIC struct symtab *varloc; STATIC struct symtab *lneloc; STATIC struct symtab *ulnloc; STATIC int decalage_de__LINE__=0; /* Pour decaler eventuellement la variable '__LINE__' (introduit le 20000512114908). */ /* Si cette valeur est negative, cela signifie qu'en fait le numero de ligne est indefini, */ /* c'est-a-dire en general trop difficile a determiner (introduit le 20000720115851 a cause */ /* de 'v $xcc/cpp$Z 20000720115851'). */ STATIC struct symtab *Nnew_line; /* Pour gerer __NEW_LINE__ */ STATIC struct symtab *uflloc; STATIC struct symtab *ufrloc; STATIC struct symtab *udiloc; STATIC struct symtab *udeloc; /* Pour gerer __DEFINE__ */ STATIC struct symtab *Ndefine; /* Pour gerer __DEFINE__ */ STATIC struct symtab *umaloc; /* Pour gerer __MACRO__ */ STATIC struct symtab *Nmacro; /* Pour gerer __MACRO__ */ STATIC struct symtab *uzero__A__loc; STATIC struct symtab *uun__A__loc; STATIC struct symtab *uplus1__A__loc; STATIC struct symtab *umoins1__A__loc; STATIC struct symtab *ucompteur__A__loc; STATIC struct symtab *ucompteur__A__8loc; STATIC struct symtab *uzero__B__loc; STATIC struct symtab *uun__B__loc; STATIC struct symtab *uplus1__B__loc; STATIC struct symtab *umoins1__B__loc; STATIC struct symtab *ucompteur__B__loc; STATIC struct symtab *ucompteur__B__8loc; STATIC struct symtab *clsloc; STATIC int trulvl; STATIC int flslvl; /* =0 expansion des macros, #0 : pas d'expansion. */ STATIC int traiter_les_defines=0; /* =0 traiter les defines, #0 : les transmettre tels quel dans le fichier "out"... */ STATIC int traiter_les_ifs_elses_endifs=0; /* =0 traiter les {if,else,endif}, #0 : les transmettre tels quel dans le fichier "out"... */ /* Ceci fut introduit le 20101214185905... */ STATIC int traiter_les_messages=0; /* =0 traiter les messages, #0 : les transmettre tels quel dans le fichier "out" (ceci */ /* fut introduit le 20101215114128). */ STATIC int traiter_les_systems=0; /* =0 traiter les system's, #0 : les transmettre tels quel dans le fichier "out" (ceci */ /* fut introduit le 20161209092439). */ STATIC int TransmettreControlesNonReconnus=0; /* =0 les controles non reconnus sont une erreur, #0 : ils sont transmis "betement" (ceci */ /* fut introduit le 20101214181121). */ struct symtab *savenp; /* Pointeur non recursif destine a distinguer 'define', 'redefine' et 'TestADef' dans la */ /* fonction 'dodef(...)'. */ sayline() { if (pflag == 0) { fprintf(fout,LINEFORM,lineno[ifno],fnames[ifno],ifno); /* L'edition de 'ifno' a ete ajoute afin d'aider la commande '$xcc/Lincludes$Z'. */ } else { } } /* Data structure guide */ /* */ /* most of the scanning takes place in the buffer: */ /* */ /* (low address) (high address) */ /* pbeg pbuf pend */ /* | <-- BUFSIZ chars --> | <-- BUFSIZ chars --> | */ /* _______________________________________________________________________ */ /* |_______________________________________________________________________| */ /* | | | */ /* |<-- waiting -->| |<-- waiting --> */ /* | to be |<-- current -->| to be */ /* | written | token | scanned */ /* | | | */ /* outp inp p */ /* */ /* *outp first CHAR not yet written to output file */ /* *inp first CHAR of current token */ /* *p first CHAR not yet scanned */ /* */ /* macro expansion: write from *outp to *inp (chars waiting to be written), */ /* ignore from *inp to *p (chars of the macro call), place generated */ /* characters in front of *p (in reverse order), update pointers, */ /* resume scanning. */ /* */ /* symbol table pointers point to just beyond the end of macro definitions; */ /* the first preceding character is the number of formal parameters. */ /* the appearance of a formal in the body of a definition is marked by */ /* 2 chars: the char WARN, and a char containing the parameter number. */ /* the first char of a definition is preceded by a zero character. */ /* */ /* when macro expansion attempts to back up over the beginning of the */ /* buffer, some characters preceding *pend are saved in a side buffer, */ /* the address of the side buffer is put on 'instack', and the rest */ /* of the main buffer is moved to the right. the end of the saved buffer */ /* is kept in 'endbuf' since there may be nulls in the saved buffer. */ /* */ /* similar action is taken when an 'include' statement is processed, */ /* except that the main buffer must be completely emptied. the array */ /* element 'inctop[ifno]' records the last side buffer saved when */ /* file 'ifno' was included. these buffers remain dormant while */ /* the file is being read, and are reactivated at end-of-file. */ /* */ /* instack[0 : mactop] holds the addresses of all pending side buffers. */ /* instack[inctop[ifno]+1 : mactop-1] holds the addresses of the side */ /* buffers which are "live"; the side buffers instack[0 : inctop[ifno]] */ /* are dormant, waiting for end-of-file on the current file. */ /* */ /* space for side buffers is obtained from 'savch' and is never returned. */ /* bufstack[0:fretop-1] holds addresses of side buffers which */ /* are available for use. */ /* */ /* --->>--- */ /* | | */ /* | | */ /* | COTOKEN DODEF <---- CONTROL */ /* | \ | / */ /* | \ | / */ /* | \ | / */ /* | \ | / */ /* | \ | / */ /* | \ | / */ /* \ | / */ /* ^ SLOOKUP */ /* | | \ */ /* | | \ */ /* | | \ */ /* | | \ */ /* | | \ */ /* | | \ */ /* | SUBST LOOKUP */ /* | | */ /* | | */ /* ----------<<----------- */ /* */ dump() /* Write part of buffer which lies between outp and inp . */ /* this should be a direct call to 'write', but the system slows */ /* to a crawl if it has to do an unaligned copy. thus we buffer. */ /* this silly loop is 15% of the total time, thus even the 'putc' */ /* macro is too slow. */ { REGISTER CHAR *p1; REGISTER FILE *f; if (((p1=outp) == inp) || (flslvl != 0)) { return; } else { } f = fout; if (p1 < inp) { if (1) /* Introduit le 20071122130909 a cause de '$LACT18' et des caracteres "exotiques" qu'a */ /* cette date, je n'arrive pas a eliminer. Pour activer cette validation, il suffit de */ /* mettre ci-dessus : */ /* */ /* if (0) */ /* */ /* a la place du 'if(1)" ci-dessus. J'ai trouve : voir 'PROGRESSION_DE_vp' qui manquait */ /* pour {__ZERO__A__,__UN__A__,__PLUS1__A__,__MOINS1__A__}... */ { } else { CHAR *pvalide; for (pvalide=p1 ; pvalide < inp ; pvalide++) { if ((*pvalide) >= 0x80) { pperror2I("un caractere exotique a ete rencontre (0x%0x)",*pvalide); /* Cas des codes superieurs a '0x7f', mais en fait ce message ne sort pas sur '$LACT18'... */ /* Au passage, ce probleme semble lie a 'ListeDesArgumentsImplicites' car ces caracteres */ /* "exotiques" en sont toujours proche. En fait le nombre de paquets consecutifs de */ /* caracteres "exotiques" vaut 5, c'est-a-dire au nombre de {__PLUS1__A__,__MOINS1__A__} que */ /* l'on trouve dans 'v $xil/defi_c1$vv$DEF GENERATION_D_UNE_LISTE_DES_ARGUMENTS_IMPLICITES'. */ } else { } } } if (1) /* Ce test mis en place le 20190412140124 ne sert a rien car, en effet, le probleme */ /* etait ailleurs ('v $xcc/cpp$Z 20190412140849'). Je le laisse malgre tout : on ne */ /* sait jamais... */ { p1 += fwrite(p1,sizeof(CHAR),inp-p1,f); /* Je rappelle le 20190412113431 que c'est bien ce 'fwrite(...)' qui produit le fichier */ /* pre-processe (en general sur 'fout'...). */ } else { while (p1 < inp) { fputc(*p1,f); /* Transfert caractere par caractere mis en place le 20190412140124 suite au probleme */ /* decrit dans 'v $xcc/cpp$Z 20190411120055' pour voir. Mais en fait, cela ne change rien... */ p1++; } } } else { } if ((p1 < 0) || (inp < 0)) { pperror2I("un pointeur negatif a ete rencontre",0); /* Introduit le 20071122114915, on ne sait jamais... */ } else { } outp = p1; } CHAR *refill(p) /* Dump buffer. save chars from inp to p. read into buffer at pbuf, */ /* contiguous with p. update pointers, return new p. */ REGISTER CHAR *p; { REGISTER CHAR *np,*op; REGISTER int ninbuf; dump(); np = pbuf-(p-inp); op = inp; if (bob(np+1)) { pperror1("token too long"); np = pbeg; p = inp+eBUFSIZ; } else { } macdam += np-inp; outp = inp = np; while (op < p) { *np++ = *op++; } p = np; for (;;) { /* Retrieve hunk of pushed-back macro text. */ if (mactop > inctop[ifno]) { op = instack[--mactop]; np = pbuf; do { while (*np++ = *op++) { } } while (op < endbuf[mactop]); pend = np-1; /* Make buffer space avail for 'include' processing. */ if (fretop < MAXFRE) { bufstack[fretop++] = instack[mactop]; } else { } return(p); } else /* Get more text from file(s). */ { maclvl = 0; if (0 < (ninbuf = fread(pbuf,sizeof(CHAR),eBUFSIZ,fin))) { pend = pbuf+ninbuf; *pend = Cnull; return(p); } else { } /* End of #include file. */ if (ifno == IFNO) /* End of input. */ { if (plvl != 0) { int n = plvl,tlin = lineno[ifno]; CHAR *tfil = fnames[ifno]; lineno[ifno] = maclin; fnames[ifno] = macfil; pperror2S("%s: unterminated macro call",macnam); lineno[ifno] = tlin; fnames[ifno] = tfil; np = p; /* Shut off unterminated quoted string. */ *np++ = '\n'; /* Supply missing parens. */ while (--n >= 0) *np++ = ')'; pend = np; *np = Cnull; if (plvl < 0) { plvl = 0; } else { } return(p); } else { } inp = p; dump(); #define MImbric1 "probleme d'imbrication des directives de conditionnalite (manque 'endif' ?) ou commentaires mal formes" #define MImbric2 "probleme d'imbrication des directives de conditionnalite (manque 'else'/'endif' ?) ou commentaires mal formes" /* Afin de raccourcir certaines lignes a suivre (introduit le 20180428001111...). */ if (trulvl != 0) { pperror2I(MImbric1" -1-",0); } else { } if (flslvl != 0) { pperror2I(MImbric2" -1-",0); } else { } if (Showdefines != 0) { int i; for (i = 0 ; i < symsiz ; i++) { if ((stab[i].name != NULL) && (stab[i].value != NULL)) { ppmessage2S("===> define : %s",stab[i].name); /* Le 19970704181453, j'ai introduit le listage de la table des symboles a la fin... */ } else { } } } else { } exit((exfail) ? ((exfail == CLASSCODE) ? CLASSCODE : RETURN_2 ) : RETURN_0); /* Parait etre la sortie "standard" de cpp... */ } else { } fclose(fin); fin = fins[--ifno]; dirs[0] = dirnams[ifno]; sayline(); } } } #define BEG 0 #define LF 1 static int state = BEG; static int speakup = 0; /* ATTENTION : a l'origine, ces 2 'int' etaient a l'interieur de 'cotoken()', */ /* ce qui est plus que bizarre pour des 'static'... */ CHAR *cotoken( p ) REGISTER CHAR *p; { REGISTER int c,i; CHAR quoc; if (state != BEG) { goto prevlf; } else { } for (;;) { again: while (!isspc(*p++)) { } switch (*(inp = p-1)) { case 0: if (eob(--p)) { p = refill(p); goto again; } else { ++p; } /* Ignore null byte. */ break; case '|': case '&': for (;;) /* Sloscan only. */ { if (*p++ == *inp) { break; } else { } if (eob(--p)) { p = refill(p); } else { break; } } break; case '=': case '!': for (;;) /* Sloscan only. */ { if (*p++ == '=') { break; } else { } if (eob(--p)) { p = refill(p); } else { break; } } break; case '<': case '>': for (;;) /* Sloscan only. */ { if ((*p++ == '=') || (p[-2] == p[-1])) { break; } else { } if (eob(--p)) { p = refill(p); } else { break; } } break; case SUITE: for (;;) { if (*p++ == '\n') { ++lineno[ifno]; break; } else { } if (eob(--p)) { p = refill(p); } else { ++p; break; } } break; case '/': for (;;) { if (*p++ == '*') /* Comment. */ { if (!passcom) { inp = p-2; dump(); ++flslvl; } else { } for (;;) { while (!iscom(*p++)) { } if (p[-1] == '*') { for (;;) { if (*p++ == '/') { goto endcom; } else { } if (eob(--p)) { if (!passcom) { inp = p; p = refill(p); } /* Split long comment. */ else { if ((p-inp) >= eBUFSIZ) { *p++ = '*'; *p++ = '/'; inp = p; p = refill(p); outp = inp = p -= 2; *p++ = '/'; *p++ = '*'; } else { p = refill(p); } } } else { break; } } } else { if (p[-1] == '\n') { ++lineno[ifno]; if ((!passcom) && (flslvl <= 1)) { putc('\n',fout); } else { } } else { if (eob(--p)) { if (!passcom) { inp = p; p = refill(p); } /* Split long comment. */ else { if ((p-inp) >= eBUFSIZ) { *p++ = '*'; *p++ = '/'; inp = p; p = refill(p); outp = inp = p -= 2; *p++ = '/'; *p++ = '*'; } else { p = refill(p); } } } else { ++p; } } } /* Ignore null byte. */ } endcom: if (!passcom) { outp = inp = p; --flslvl; goto again; } else { } break; } else { } if (eob(--p)) { p = refill(p); } else { break; } } break; case '"': case '\'': quoc = p[-1]; for (;;) { while (!isquo(*p++)) { } if (p[-1] == quoc) { break; } else { } if (p[-1] == '\n') /* Bare \n terminates quotation. */ { --p; break; } else { } if (p[-1] == SUITE) { for (;;) { if (*p++ == '\n') /* Escaped \n ignored. */ { ++lineno[ifno]; break; } else { } if (eob(--p)) { p = refill(p); } else { ++p; break; } } } else { if (eob(--p)) { p = refill(p); } else { ++p; } } /* It was a different quote character. */ } break; case WARN: { int ii; dump(); speakup = 0; for (ii = sizeof(int)/sizeof(CHAR) ; --ii >= 0 ; ) { if (eob(p)) { p = refill(p); } else { } speakup |= (*p++ & cCHAR(0xFF)) << (ii*8); } inp = outp = p; break; } case '\n': ++lineno[ifno]; if (isslo) { state=LF; return(p); } else { } prevlf: if (speakup) { inp = p; dump(); lineno[ifno] = speakup+1; sayline(); speakup = 0; } else { } state = BEG; for (;;) { /* Ignore formfeeds and vertical tabs which may be just before the SALT. */ /* Le 20000616122345, j'ai ajoute les tabulations et les espaces... */ if ((*p == '\f') || (*p == '\v') || (*p == ' ') || (*p == '\t')) { REGISTER CHAR *s = p; while ((*++s == '\f') || (*s == '\v') || (*s == ' ') || (*s == '\t')) /* Le 20000616122345, j'ai ajoute les tabulations et les espaces... */ { } if (*s == var_SALT) { /* Get the SALT to the front! */ *s = *p; *p = var_SALT; } else { } } else { } if (*p++ == var_SALT) { return(p); /* C'est ici que l'on detecte les lignes de commandes du pre-processeur, lors de ce */ /* retour de cotoken(), on se trouve sur la commande elle-meme (derriere 'var_SALT'). */ } else { } if (eob(inp = --p)) { p = refill(p); } else { goto again; } } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': for (;;) { while (isnum(*p++)) { } if (eob(--p)) { p = refill(p); } else { break; } } break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': #if scw1 # define tmac1(c,bit) \ if (!xmac1(c,bit,&)) \ { \ goto nomac; \ } \ else \ { \ } # define xmac1(c,bit,op) \ ((macbit+COFF)[c] op (bit)) #else scw1 # define tmac1(c,bit) # define xmac1(c,bit,op) #endif scw1 #if scw2 # define tmac2(c0,c1,cpos) \ if (!xmac2(c0,c1,cpos, & )) \ { \ goto nomac; \ } \ else \ { \ } # define xmac2(c0,c1,cpos,op) \ ((macbit+COFF)[(t21+COFF)[c0]+(t22+COFF)[c1]] op (t23+COFF+cpos)[c0]) #else scw2 # define tmac2(c0,c1,cpos) # define xmac2(c0,c1,cpos,op) #endif scw2 if (flslvl != 0) { goto nomac; } else { } #define DERIVATEUR_FORMEL \ if (((*p) == var_SALT) && (var_CONC != Cnull)) \ { \ *p = var_CONC; \ } \ else \ { \ } \ /* L'aide a la derivation formelle n'a lieu que si 'var_CONC' n'est pas nul... */ for (;;) { c = p[-1]; tmac1(c,b0); DERIVATEUR_FORMEL; i = *p++; if (!isid(i)) { goto endid; } else { } tmac1(i,b1); tmac2(c,i,0); DERIVATEUR_FORMEL; c = *p++; if (!isid(c)) { goto endid; } else { } tmac1(c,b2); tmac2(i,c,1); DERIVATEUR_FORMEL; i = *p++; if (!isid(i)) { goto endid; } else { } tmac1(i,b3); tmac2(c,i,2); DERIVATEUR_FORMEL; c = *p++; if (!isid(c)) { goto endid; } else { } tmac1(c,b4); tmac2(i,c,3); DERIVATEUR_FORMEL; i = *p++; if (!isid(i)) { goto endid; } else { } tmac1(i,b5); tmac2(c,i,4); DERIVATEUR_FORMEL; c = *p++; if (!isid(c)) { goto endid; } else { } tmac1(c,b6); tmac2(i,c,5); DERIVATEUR_FORMEL; i = *p++; if (!isid(i)) { goto endid; } else { } tmac1(i,b7); tmac2(c,i,6); tmac2(i,0,7); DERIVATEUR_FORMEL; while (isid(*p++)) { DERIVATEUR_FORMEL; /* ATTENTION, ce 'DERIVATEUR_FORMEL' avait ete omis et a ete rajoute le 1993031500. */ } if (eob(--p)) { refill(p); p = inp+1; continue; } else { } goto lokid; endid: if (eob(--p)) { refill(p); p = inp+1; continue; } else { } tmac2(p[-1],0,-1+(p-inp)); lokid: /* ATTENTION, il me semblait qu'il manquait ici (le 1993031500) un : */ /* */ /* DERIVATEUR_FORMEL; */ /* */ /* mais cela ne semble pas etre le cas, car cela perturbe '$xtg/derivees.11$C'... */ slookup(inp,p,0); if (newp != 0) { p = newp; goto again; } else { break; } nomac: /* ATTENTION, il me semblait qu'il manquait ici (le 1993031500) un : */ /* */ /* DERIVATEUR_FORMEL; */ /* */ /* mais cela ne semble pas etre le cas, car cela perturbe '$xtg/derivees.11$C'... */ while (isid(*p++)) { DERIVATEUR_FORMEL; /* ATTENTION, ce 'DERIVATEUR_FORMEL' avait ete omis et a ete rajoute le 1993031500. */ } if (eob(--p)) { p = refill(p); goto nomac; } else { break; } } break; } /* End of switch. */ if (isslo) { return(p); } else { } } /* End of infinite loop. */ } CHAR *skipbl(p) /* Get next non-blank token. */ REGISTER CHAR *p; { do { outp = inp = p; p = cotoken(p); } while ((toktyp+COFF)[*inp] == BLANK); return(p); } CHAR *unfill( p ) REGISTER CHAR *p; { /* Take <= BUFSIZ chars from right end of buffer and put */ /* them on instack. slide rest of buffer to the right, */ /* update pointers, return new p. */ REGISTER CHAR *np,*op; REGISTER int d; if (mactop >= MAXFRE) { pperror2S("%s: too much pushback",macnam); p = inp = pend; /* Begin flushing pushback. */ dump(); while (mactop > inctop[ifno]) { p = refill(p); p = inp = pend; dump(); } } else { } if (fretop > 0) { np = bufstack[--fretop]; } else { np = savch; savch += eBUFSIZ; if (savch >= (sbf+eSBSIZE)) { pperror1("no space"); exit((exfail) ? ((exfail == CLASSCODE) ? CLASSCODE : RETURN_2) : RETURN_0); } else { } *savch++ = Cnull; } instack[mactop] = np; op = pend-eBUFSIZ; if (op < p) { op = p; } else { } for (;;) /* Out with old. */ { while (*np++ = *op++) { } if (eob(op)) { break; } else { } } endbuf[mactop++] = np; /* Mark end of saved text. */ np = pbuf+eBUFSIZ; op = pend-eBUFSIZ; pend = np; if (op < p) { op = p; } else { } while (outp < op) { /* Slide over new. */ *--np = *--op; } if (bob(np)) { pperror1("token too long"); } else { } d = np-outp; outp += d; inp += d; macdam += d; return(p+d); } CHAR *doincl(p) REGISTER CHAR *p; { int filok,inctype; REGISTER CHAR *cp; CHAR **dirp,*nfil; CHAR filname[eBUFSIZ]; /* Nom du fichier argument d'un include. */ p = skipbl(p); /* Nota : dans le cas, par exemple, de '#include F(...)' ou 'F' est */ /* une macro, on ne revient pas de cet appel a 'skipbl()', et le */ /* resultat du pre-processing de 'F(...)' est envoye dans le reste */ /* du flot par 'dump()' ; je n'ai pas reussi a corriger ce probleme... */ cp = filname; if (*inp++ == '<') /* Special <> syntax. */ { inctype = 1; ++flslvl; /* Prevent macro expansion. */ for (;;) { outp = inp = p; p = cotoken(p); if (*inp == '\n') { --p; *cp = Cnull; break; } else { } if (*inp == '>') { *cp = Cnull; break; } else { } while (inp < p) { *cp++ = *inp++; } } --flslvl; /* Reenable macro expansion. */ } else { if (inp[-1] == '"') /* Regular "" syntax. */ { inctype = 0; while (inp < p) { *cp++ = *inp++; } if (*--cp == '"') { *cp = Cnull; } else { } } else { pperror2I("bad syntax for the argument of 'include'/'Einclude'/'Winclude'/'message'/'system'/'warning' ; first character=0x%02x" ,inp[-1] ); /* La cause peut en etre quelque chose du type : */ /* */ /* #include xrr/univers.11.I" */ /* */ /* alors que 'xrr' n'a pas ete definie dans '$xcc/cpp$D/cpp$Y' ; ce probleme s'est vu le */ /* 19970408111221 dans '$xrr/univers.10$K'. */ inctype = 2; } } /* Flush current file to \n , then write \n. */ ++flslvl; do { outp = inp = p; p = cotoken(p); } while (*inp != '\n'); --flslvl; inp = p; dump(); if (inctype == 2) { return(p); } else { } /* Look for included file. */ if (ifno+1 >= MAXINC) { pperror2I("Unreasonable include nesting",0); return(p); } else { } if ((nfil = savch) > (sbf+eSBSIZE-eBUFSIZ)) { pperror1("no space"); exit((exfail) ? ((exfail == CLASSCODE) ? CLASSCODE : RETURN_2) : RETURN_0); } else { } filok = 0; for (dirp = dirs+inctype ; *dirp ; ++dirp) { if ((filname[0] == '/') || (**dirp == Cnull)) { strcpy(nfil,filname); } else { strcpy(nfil,*dirp); strcat(nfil,"/"); strcat(nfil,filname); } if ((message == MESSAGE_0) || (message == MESSAGE_2) || (message == MESSAGE_4)) { if (NULL != (fins[ifno+1] = fopen(nfil,READ))) { if (message == MESSAGE_4) { CHAR *nfilw; STATIC FILE *finw; nfilw=nfil; strcat(nfilw,getenv("v")); while (NULL != (finw = fopen(nfilw,READ))) { sleep(1); fclose(finw); /* Tant que le fichier a inclure est verrouille, on attend... */ } } else { } filok = 1; fin = fins[++ifno]; break; } else { } } else { } } if (filok == 0) { if (message == MESSAGE_0) { pperror2S("Can't find include file %s",filname); } else { } if (message == MESSAGE_4) { pperror2S("Can't find Winclude file %s",filname); } else { } if (message == MESSAGE_1) { ppmessage2S("===> Message : %s",filname); } else { } if (message == MESSAGE_5) { ppmessage2S("===> Warning : %s",filname); } else { } if (message == MESSAGE_3) { system(filname); /* Execution de la commande argument contenue dans 'filname' via '/bin/sh' (introduit */ /* le 20161209092439... */ } else { } } else { if (ShowIncludes != 0) { ppmessage2S("===> Include : %s",filname); /* Edition introduite le 20101214162107... */ } else { } lineno[ifno] = 1; fnames[ifno] = cp = nfil; while (*cp++) { } savch = cp; dirnams[ifno] = dirs[0] = trmdir(copy(nfil)); sayline(); /* Save current contents of buffer. */ while (!eob(p)) { p = unfill(p); } inctop[ifno] = mactop; } return(p); } equfrm(a,p1,p2) REGISTER CHAR *a,*p1,*p2; { REGISTER CHAR c; int flag; c = *p2; *p2 = Cnull; flag = strcmp(a,p1); *p2 = c; return(flag == SAME); } CHAR *dodef( p) /* Process '#define' */ CHAR *p; { REGISTER CHAR *pin,*psav,*cf; CHAR **pf,**qf; int b,c,params; int ex_blank; /* Used to ignore extra blanks in token-string. */ int sav_passcom = passcom; /* Saved passcom, used to reset it. */ struct symtab *np; CHAR *oldval,*oldsavch; CHAR *formal[MAXFRM]; /* Formal[n] is name of nth formal. */ CHAR formtxt[eBUFSIZ]; /* Space for formal names. */ pf = formal; /* J'ai rajoute cette initialisation, a cause de : */ /* */ /* 'Variable "pf" is possibly referenced before set' */ /* */ /* sur 'SYSTEME_ES9000'. */ if (savch > (sbf+eSBSIZE-eBUFSIZ)) { pperror1("too much defining"); return(p); } else { } oldsavch = savch; /* To reclaim space if redefinition. */ ++flslvl; /* Prevent macro expansion during 'define'. */ p = skipbl(p); pin = inp; if ((toktyp+COFF)[*pin] != IDENT) { ppwarn1("illegal macro name"); while (*inp != '\n') { p = skipbl(p); } return(p); } else { } np = slookup(pin,p,1); Ndefine = np; /* Lors de la prochaine reference a __DEFINE__ c'est le nom courant defini que l'on */ /* recuperera, mais ATTENTION, ce n'est pas recursif... */ if (oldval = np->value) { /* Was previously defined. */ savch = oldsavch; } else { } b = 1; cf = pin; while (cf < p) /* Update macbit. */ { c = *cf++; xmac1(c,b, |= ); b = (b+b) & cCHAR(0xFF); if (cf != p) { xmac2(c,*cf,-1+(cf-pin), |= ); } else { xmac2(c,0,-1+(cf-pin), |= ); } } params = 0; outp = inp = p; p = cotoken(p); pin = inp; if (*pin == '(') /* With parameters; identify the formals. */ { cf = formtxt; pf = formal; for (;;) { p = skipbl(p); pin = inp; if (*pin == '\n') { --lineno[ifno]; --p; pperror2S("%s: missing)",np->name); break; } else { } if (*pin == ')') { break; } else { } if (*pin == ',') { continue; } else { } if (*pin == SUITE) { /* JF COLONNA. */ continue; } else { } /* JF COLONNA. */ if ((toktyp+COFF)[*pin] != IDENT) { c = *p; *p = Cnull; pperror2S("bad formal: %s",pin); *p = c; } else { if (pf >= &formal[MAXFRM]) { c = *p; *p = Cnull; pperror2S("too many formals: %s",pin); *p = c; } else { CHAR **pf2; REGISTER CHAR *cf2; pf2=pf; /* Afin de ne tester que les formals deja surs, du premier jusqu'a l'avant-dernier rencontre */ cf2=cf; /* Pointeur sur le formal courant que l'on veut valider. */ *pf++ = cf; while (pin < p) { *cf++ = *pin++; } /* Memorisation du formal courant avant validation (a cause du null de fin...). */ *cf++ = Cnull; { REGISTER CHAR *cf1; CHAR **pf1; pf1 = formal; /* Pointeur des pointeurs des formals (du premier jusqu'a l'avant dernier rencontre). */ while (pf1 < pf2) { cf1 = *pf1++; /* Pointeur du formal courant deja valide (du premier jusqu'a l'avant dernier rencontre). */ if (strcmp(cf2,cf1) == 0) { pperror2S("duplication of formal: %s",cf2); } else { } } } ++params; } } } if (params == 0) { /* #define foo() ... */ --params; } else { } } else { if (*pin == '\n') { --lineno[ifno]; --p; } else { } } /* Remember beginning of macro body, so that we can warn if a redefinition is different */ /* from old value. */ oldsavch = psav = savch; passcom = 1; /* Make cotoken() return comments as tokens. */ ex_blank = 1; /* Must have some delimiter - might as well be blank. */ for (;;) /* Accumulate definition until linefeed. */ { outp = inp = p; p = cotoken(p); pin = inp; if ((*pin == SUITE) && (pin[1] == '\n')) /* Ignore escaped lf. */ { if (!ex_blank) /* Replace it with a blank. */ { *psav++ = ' '; ex_blank = 1; } else { } putc('\n',fout); continue; } else { } if (*pin == '\n') { break; } else { } if ((toktyp+COFF)[*pin] == BLANK) /* Skip extra blanks. */ { if (ex_blank) { continue; } else { } *pin = ' '; /* Force it to be a "real" blank. */ ex_blank = 1; } else { ex_blank = 0; } if ((*pin == '/') && (pin[1] == '*')) /* Skip comment. */ { /* Except for \n's. */ while (pin < p) { if (*pin++ == '\n') { putc('\n',fout); } else { } } continue; } else { } if (params) /* Mark the appearance of formals in the definiton. */ { if ((toktyp+COFF)[*pin] == IDENT) { for (qf = pf ; --qf >= formal ; ) { if (equfrm(*qf,pin,p)) { *psav++ = qf-formal+1; *psav++ = WARN; /* C'est ici que les parametres formels ("formals") des macros sont remplaces par */ /* le caractere 'WARN' et un caractere contenant le numero qui leur est attribue... */ pin = p; break; } else { } } } /* Inside quotation marks, too. */ else { if ((*pin == '"') || (*pin == '\'')) { CHAR quoc = *pin; for (*psav++ = *pin++ ; ((pin < p) && (*pin != quoc)) ; ) { while ((pin < p) && (!isid(*pin))) { if ((*pin == '\n') && (pin[-1] == SUITE)) { putc('\n',fout); psav--; /* No \ */ pin++; /* No \n. */ } else { *psav++ = *pin++; } } cf = pin; while ((cf < p) && (isid(*cf))) { ++cf; } for (qf = pf ; --qf >= formal ; ) { if (equfrm(*qf,pin,cf)) { *psav++ = qf-formal+1; *psav++ = WARN; /* C'est ici que les parametres formels ("formals") des macros sont remplaces par */ /* le caractere 'WARN' et un caractere contenant le numero qui leur est attribue... */ pin = cf; break; } else { } } while (pin < cf) { *psav++ = *pin++; } } } else { } } } else { } while (pin < p) { if ((*pin == '\n') && (pin[-1] == SUITE)) { putc('\n',fout); psav--; /* No \. */ pin++; /* No \n. */ } else { *psav++ = *pin++; } } } passcom = sav_passcom; /* Restore to "real" value. */ if (psav[-1] == ' ') { /* If token-string ended with a blank. */ psav--; } else { } /* Then it is unnecessary - throw away. */ *psav++ = params; *psav++ = Cnull; if (((cf = oldval) != NULL) && (savenp != redefloc) && (savenp != defmloc)) /* Redefinition avec 'define' ou 'TestADef'. */ { --cf; /* Skip no. of params, which may be zero. */ while (*--cf) /* Go back to the beginning. */ { } if (((1) || (0 != strcmp(++cf,oldsavch))) && (savenp != tdefloc)) /* Redefinition different from old. */ /* ATTENTION : maintenant, meme une redefinition avec une valeur */ /* identique provoque une erreur ; afin de ne pas modifier le */ /* source de 'cpp', j'ai donc rajoute la condition '(1) || ...' qui */ /* est donc toujours vraie... */ { --lineno[ifno]; ppwarn("%s redefined",np->name); ++lineno[ifno]; np->value = psav-1; } else { psav = oldsavch; } /* Identical redef.; reclaim space. */ } else { if ((DefDirectives != 0) && (cf == NULL) && (savenp == redefloc)) /* Usage de 'redefine' d'un symbole qui ne pre-existe pas... */ /* */ /* Test et sequence introduite le 20090913183034 afin d'editer un message d'erreur si */ /* un symbole fait l'objet d'un 'redefine' alors qu'il ne pre-existe pas... */ /* */ /* Le test de 'DefDirectives' est destine a eviter le message : */ /* */ /* define does not exist ('redefine' --> 'define') */ /* */ /* lors de la definition : */ /* */ /* defloc = ppsym("define"); */ /* */ { --lineno[ifno]; ppwarn("%s does not exist ('redefine' --> 'define')",np->name); ++lineno[ifno]; } else { } np->value = psav-1; /* ATTENTION, on n'oubliera pas que l'on passe ici lors de la definition des symboles */ /* via '#define', mais aussi via 'stsym(...)' en ce qui concerne les "mots-clefs"... */ /* Enfin, 'psav' pointe sur la fin de la valeur et non sur le debut lorsque l'on est ici. */ } --flslvl; inp = pin; savch = psav; return(p); } #define fasscan() ptrtab = fastab+COFF #define sloscan() ptrtab = slotab+COFF CHAR *control( p ) /* Find and handle preprocessor control lines. */ REGISTER CHAR *p; { REGISTER struct symtab *np; for (;;) { TransmettreLesControles: fasscan(); p = cotoken(p); /* On pointe ici, eventuellement sur une commande au pre-processeur. */ if (*inp == '\n') { ++inp; } else { } dump(); sloscan(); p = skipbl(p); *--inp = var_SALT; outp = inp; ++flslvl; np = slookup(inp,p,0); --flslvl; message = -1; /* A priori, ni 'include', ni 'message'. */ if ((np == defloc) || (np == Defloc) || (np == redefloc) || (np == tdefloc) || (np == defmloc)) /* 'define' ou 'define' ou 'redefine' ou 'TestADef' ou 'mdefine'. */ { if (flslvl == 0) { if ((traiter_les_defines == 0) || (np == Defloc)) { savenp = np; /* Afin de pouvoir faire la difference entre 'define', 'redefine' et 'TestADef' dans la */ /* fonction 'dodef(...)'. */ p = dodef(p); continue; /* Cas general ou l'on traite les defines ou cas de la commande 'define'... */ } else { goto TransmettreLesControles; /* Cas ou les defines sont transmis tels quel dans le fichier "out"... */ } } else { } } else { if ((np == incloc) || (np == Eincloc) || (np == Wincloc)) /* Include ou Einclude ou Winclude. */ { if (flslvl == 0) { if (np == incloc) { message = MESSAGE_0; /* Include. */ } else { } if (np == Eincloc) { message = MESSAGE_2; /* Einclude. */ } else { } if (np == Wincloc) { message = MESSAGE_4; /* Winclude. */ } else { } p = doincl(p); continue; } else { } } else { if ((np == mesloc) || (np == warloc)) /* Message ou Warning (introduit le 20210903175906). */ { if (traiter_les_messages == 0) { if (flslvl == 0) { if (np == mesloc) { message = MESSAGE_1; } else { if (np == warloc) { message = MESSAGE_5; } else { pperror1("Anomalie avec 'message' ou 'warning'"); } } p = doincl(p); continue; } else { } } else { goto TransmettreLesControles; /* Cas ou tous les messages sont transmis tels quel dans le fichier "out"... */ } } else { if (np == sysloc) /* System. */ { if (traiter_les_systems == 0) { if (flslvl == 0) { message = MESSAGE_3; p = doincl(p); continue; } else { } } else { goto TransmettreLesControles; /* Cas ou tous les system's sont transmis tels quel dans le fichier "out"... */ } } else { if ( (traiter_les_ifs_elses_endifs == 1) && ( (np == ifloc) || (np == Aifloc) || (np == elsloc) || (np == elsiloc) || (np == Eifloc) || (np == eifloc) || (np == ifdloc) || (np == Aifdloc) || (np == elsdloc) || (np == Eifdloc) || (np == eifdloc) || (np == ifnloc) || (np == Aifndloc) || (np == elsndloc) || (np == Eifndloc) || (np == eifndloc) ) ) { goto TransmettreLesControles; /* Cas ou tous les controles de test sont transmis tels quel dans le fichier "out"... */ } else { if (np == ifnloc) /* Ifndef. */ { ++flslvl; p = skipbl(p); np = slookup(inp,p,0); --flslvl; if ((flslvl == 0) && (np->value == 0)) { ++trulvl; } else { ++flslvl; } } else { if (np == ifdloc) /* Ifdef. */ { ++flslvl; p = skipbl(p); np = slookup(inp,p,0); --flslvl; if ((flslvl == 0) && (np->value != 0)) { ++trulvl; } else { ++flslvl; } } else { if ( (np == eifloc) || (np == eifdloc) || (np == eifndloc) || (np == Eifloc) || (np == Eifdloc) || (np == Eifndloc) ) /* Endif/endifdef/endifndef/Eif/Eifdef/Eifndef. */ { if (flslvl != 0) { if (--flslvl == 0) { sayline(); } else { } } else { if (trulvl) { --trulvl; } else { pperror2I("If-less endif",0); } } } else { if ( (np == elsloc) || (np == elsiloc) || (np == elsdloc) || (np == elsndloc) || (np == Aifloc) || (np == Aifdloc) || (np == Aifndloc) ) /* Else/elseif/elseifdef/elseifndef/Aif/Aifdef/Aifndef. */ { if (flslvl != 0) { if (--flslvl != 0) { ++flslvl; } else { ++trulvl; sayline(); } } else { if (trulvl) { ++flslvl; --trulvl; } else { pperror2I("If-less else",0); } } } else { if ( (np == udfloc) || (np == Udfloc) || (np == nodefloc) || (np == notdefloc) || (np == nydefloc) ) /* Undefine ('undef' ou 'Undef' ou 'nodefine' ou 'nydefine' ou 'NTestADef'). */ { if (flslvl == 0) /* Detection des '#undef' sur des symboles non definis. */ { if (traiter_les_defines == 0) { CHAR *pinundef; struct symtab *Sundef; ++flslvl; p = skipbl(p); pinundef = inp; Sundef = slookup(pinundef,p,1); if ((Sundef->value != 0) && (np == nodefloc)) { ppwarn("'nodefine' d'un symbole ('%s') defini" ,Sundef->name ); } else { } if ((Sundef->value != 0) && (np == notdefloc)) { ppwarn("'nTestADef' d'un symbole ('%s') defini" ,Sundef->name ); } else { } if ((Sundef->value != 0) && (np == nydefloc)) { ppwarn("'nydefine' d'un symbole ('%s') defini" ,Sundef->name ); } else { } if ((Sundef->value == 0) && (np == udfloc)) { ppwarn("'undef' d'un symbole ('%s') non defini" ,Sundef->name ); } else { slookup(inp,p,DROP); } /* 'undef' d'un symbole defini anterieurement. */ --flslvl; } else { goto TransmettreLesControles; /* Cas ou les defines sont transmis tels quel dans le fichier "out"... */ } } else { } } else { if (np == ifloc) /* If. */ { newp = p; if ((flslvl == 0) && (yyparse())) { ++trulvl; } else { ++flslvl; } p = newp; } else { if (np == lneloc) /* Line. */ { if ((flslvl == 0) && (pflag == 0)) { REGISTER CHAR *s; REGISTER int ln; outp = inp = p; do_line: *--outp = '#'; /* Nota : on ne met pas 'var_SALT', car l'option '-P' est en fait */ /* destinee au compilateur 'C', qui ne comprend que '#'... */ /* make sure that the whole directive has been read. */ s = p; while ((*s) && (*s != '\n')) { s++; } if (eob(s)) { p = refill(s); } else { } /* Eat the line number. */ s = inp; while ((toktyp+COFF)[*s] == BLANK) { s++; } ln = 0; while (isdigit(*s)) { ln = ln*10 + *s++ - '0'; } if (ln) { lineno[ifno] = ln-1; } else { pperror1("bad number for #line"); } /* Eat the optional "filename". */ while ((toktyp+COFF)[*s] == BLANK) { s++; } if (*s != '\n') { if (*s != '"') { pperror1("bad file for #line"); } else { REGISTER CHAR *t = savch; for (;;) { if (*++s == '"') { break; } else { if ((*s == '\n') || (*s == Cnull)) { pperror1("bad file for #line"); break; } else { } } *t++ = *s; } *t++ = Cnull; if (strcmp(savch,fnames[ifno])) { fnames[ifno] = savch; savch = t; } else { } } } else { } /* Push it all along to be eventually printed. */ while (*inp != '\n') { p = cotoken(p); } continue; } else { } } else { if (np == clsloc) /* Class. */ { exfail = CLASSCODE; } /* Return value. */ else { if (*++inp == '\n') { /* Allows blank line after #. */ outp = inp; } else { if (isdigit(*inp)) /* Pass thru line directives. */ { outp = p = inp; goto do_line; } else { outp = p = --inp; if ((*p) != var_SALT) { pperror2I("erreur cpp (undefined control)" ,0 ); } else { if (TransmettreControlesNonReconnus == 0) /* Test introduit le 20101214181121... */ { if (var_EXTE == Cnull) { pperror2I("undefined control",0); } else { if (traiter_les_defines == 0) /* Ce test conditionnant le 'goto TransmettreLesControles' suivant a ete ajoute le */ /* 20000619155239 car il semble manquer... */ { } else { *p = var_EXTE; goto TransmettreLesControles; /* Lorsque l'on rencontre une directive non reconnue, elle peut etre inseree dans le fichier */ /* de sortie avec eventuellement un caractere d'introduction different de 'var_SALT'... */ } } } else { *p = var_EXTE; goto TransmettreLesControles; /* Transmission d'un controle non reconnu (introduit le 20101214181121). */ } } } } } } } } } } } } } } } } } /* Flush to lf. */ ++flslvl; while (*inp != '\n') { outp = inp = p; p = cotoken(p); } --flslvl; } statement_not_reached: /* Cette etiquette pour eviter que certains compilateurs remarquent que le 'return(0)' qui */ /* suit ne peut jamais etre execute... */ return(0); } struct symtab *stsym(s) /* Le 20190120101149 je note que l'on ne passe ici que pour les symboles predefinis (par */ /* exemple : {"define","mdefine","redefine",...}) ainsi que ceux qui sont definis a */ /* l'exterieur via "-D...". */ REGISTER CHAR *s; { CHAR buf[eBUFSIZ]; REGISTER CHAR *p; /* Make definition look exactly like end of #define line */ /* copy to avoid running off end of world when param list is at end. */ p = buf; while (*p++ = *s++) { } p = buf; if (1 == 0) { while (isid(*p++)) { } } else { while (ifonct(*p++)) /* Skip first identifier. */ /* */ /* Il semblerait que le probleme du 20190119115348 evoque ci-apres vienne de ce "Skip" et */ /* donc de la presence de la parenthese ouvrante "(" qui n'est pas un caractere alphabetique */ /* (ce que testerait 'isid(...)' ci-dessus). Alors l'ensemble "(a,b)=(a*b)" est completement */ /* ignore... */ /* */ /* Le 20190120101149, 'isid(...)' a ete remplacee par 'ifonct(...)' pour resoudre ce */ /* probleme... */ { } } if (*--p == '=') { *p++ = ' '; /* Dans le cas d'un signe "=", ce dernier est remplace par un espace afin que : */ /* */ /* -Dsymbole=definition */ /* */ /* ressemble a : */ /* */ /* #define symbole definition */ /* */ while (*p++) { } } else { s = fCHAR(" 1"); /* Dans le cas d'une definition sans valeur ("-Dsymbole") il est attribue a "symbole" */ /* la valeur "1" qui correspond a {'VRAI','EXIST',...}. Cette remarque a ete faite le */ /* 20190119115348 alors que j'essayai des "-D"s du type : */ /* */ /* -D"fonction(a,b)=(a+b)" */ /* */ /* qui ne marche pas a cette date et qui se limite a definir justement "fonction=1" en */ /* ignorant les arguments "(a,b)" et la definition "=(a+b)". On notera que '$CPP' l'accepte */ /* correctement... */ while (*p++ = *s++) { } } pend = p; *--p = '\n'; sloscan(); savenp = defloc; /* Afin de faire comme si c'etait un 'define' dans la fonction 'dodef(...)'. */ dodef(buf); return(lastsym); } struct symtab *ppsym(s) /* Kludge. */ CHAR *s; { REGISTER struct symtab *sp; cinit = var_SALT; *savch++ = var_SALT; sp = stsym(s); --sp->name; cinit = 0; return(sp); } int yy_errflag; /* TRUE when pperror called by yyerror(). */ /* VARARGS1. */ ppmessage2S(s,x) /* Fonction introduite le 20101214162107... */ CHAR *s; CHAR *x; { fprintf(stderr,s,x); fprintf(stderr,"\n"); } pperror1(s) CHAR *s; { if (fnames[ifno][0]) { fprintf(stderr,"Error : %s: ",fnames[ifno]); } else { fprintf(stderr,"Error : "); } fprintf(stderr,"%d: ",lineno[ifno]); fprintf(stderr,s); if (yy_errflag) { fprintf(stderr," (in preprocessor if)\n"); } else { fprintf(stderr,"\n"); } if (exfail < CLASSCODE-1) { ++exfail; } else { } } pperror2I(s,x) CHAR *s; int x; { if (fnames[ifno][0]) { fprintf(stderr,"Error : %s: ",fnames[ifno]); } else { fprintf(stderr,"Error : "); } fprintf(stderr,"%d: ",lineno[ifno]); fprintf(stderr,s,x); if (yy_errflag) { fprintf(stderr," (in preprocessor if)\n"); } else { fprintf(stderr,"\n"); } if (exfail < CLASSCODE-1) { ++exfail; } else { } } pperror2S(s,x) CHAR *s; CHAR *x; { if (fnames[ifno][0]) { fprintf(stderr,"Error : %s: ",fnames[ifno]); } else { fprintf(stderr,"Error : "); } fprintf(stderr,"%d: ",lineno[ifno]); fprintf(stderr,s,x); if (yy_errflag) { fprintf(stderr," (in preprocessor if)\n"); } else { fprintf(stderr,"\n"); } if (exfail < CLASSCODE-1) { ++exfail; } else { } } #define GENERE_pperror(impression) \ /* Procedure introduire le 20210301160823 pour corriger le probleme decrit lors de la mise */ \ /* en place de l'allocation dynamique ('v $xcpp/beau_cpp$c ALLOCATION_STATIQUE')... */ \ { \ if (fnames[ifno][0]) \ { \ fprintf(stderr,"Error : %s: ",fnames[ifno]); \ } \ else \ { \ fprintf(stderr,"Error : "); \ } \ \ fprintf(stderr,"%d: ",lineno[ifno]); \ \ impression; \ \ if (yy_errflag) \ { \ fprintf(stderr," (in preprocessor if)\n"); \ } \ else \ { \ fprintf(stderr,"\n"); \ } \ \ if (exfail < CLASSCODE-1) \ { \ ++exfail; \ } \ else \ { \ } \ } pperror(s,x,y) /* On notera le 20210301160823 que l'argument 'x' n'est pas type car, en effet, il n'est */ /* pas connu a priori, contrairement a l'argument 'x' de 'yypperror(...)' qui lui l'est... */ CHAR *s; { GENERE_pperror(fprintf(stderr,s,x,y);); } yypperror(s,x) /* Fonction introduire le 20210301160823 pour corriger le probleme decrit lors de la mise */ /* en place de l'allocation dynamique ('v $xcpp/beau_cpp$c ALLOCATION_STATIQUE')... */ CHAR *s; CHAR *x; /* C'est ce typage introduit le 20210301160823 qui a finalement fait disparaitre le */ /* probleme "Segmentation fault" du 20210228102007... */ { GENERE_pperror(fprintf(stderr,s,x);); } yyerror(s,a,b) CHAR *s; { yy_errflag = 1; pperror(s,a,b); yy_errflag = 0; } ppwarn1(s) CHAR *s; { int fail = exfail; exfail = -1; pperror1(s); exfail = fail; } ppwarn(s,x) CHAR *s; CHAR *x; { int fail = exfail; exfail = -1; pperror2S(s,x); exfail = fail; } struct symtab *lookup(namep,enterf) CHAR *namep; { REGISTER CHAR *np,*snp; REGISTER int c,i; int around; REGISTER struct symtab *sp; /* Namep had better not be too long (currently, <=NCPS chars) */ np = namep; around = 0; i = cinit; while (c = *np++) { i += i+c; } c = i; /* C=i for register usage on pdp11. */ c %= symsiz; if (c < 0) { c += symsiz; } else { } sp = &stab[c]; /* Acces de type "hash-coding" a la table des symboles... */ while (snp = sp->name) { np = namep; while (*snp++ == *np) { if (*np++ == Cnull) { if (enterf == DROP) { sp->name[0] = DROP; sp->value = 0; } else { } return(lastsym = sp); } else { } } if (--sp < &stab[0]) { if (around) { pperror2I("too many defines",0); exit((exfail) ? ((exfail == CLASSCODE) ? CLASSCODE : RETURN_2) : RETURN_0); } else { ++around; sp = &stab[symsiz-1]; } } else { } } if (enterf == 1) { sp->name = namep; } else { } return(lastsym = sp); } struct symtab *slookup(p1,p2,enterf) REGISTER CHAR *p1,*p2; int enterf; { REGISTER CHAR *p3; CHAR c2,c3; struct symtab *np; c2 = *p2; /* Mark end of token. */ *p2 =Cnull; if ((p2-p1) > NCPS) { p3 = p1+NCPS; } else { p3 = p2; } c3 = *p3; /* Truncate to NCPS chars or less. */ *p3 =Cnull; if (enterf == 1) { p1 = copy(p1); } else { } np = lookup(p1,enterf); /* Ici on recherche la valeur associee au nom 'p1' */ *p3 = c3; *p2 = c2; if ((np->value != 0) && (flslvl == 0)) { newp = subst(p2,np); } else { newp = 0; } return(np); } CHAR *subst(p,sp) REGISTER CHAR *p; struct symtab *sp; { static CHAR match[] = "%s: argument mismatch"; static CHAR match1[] = "%s: argument mismatch (pas assez d'arguments a l'appel)"; static CHAR match2[] = "%s: argument mismatch (trop d'arguments a l'appel)"; static CHAR match3[] = "%s: il manque les arguments d'appel (1)"; static CHAR match4[] = "%s: il manque les arguments d'appel (2)"; REGISTER CHAR *ca,*vp; int params,save_params; CHAR *actual[MAXFRM]; /* Actual[n] is text of nth actual. */ CHAR acttxt[eBUFSIZ]; /* Space for actuals. */ if (0 == (vp = sp->value)) { return(p); } else { } if ((p-macforw) <= macdam) { if ((++maclvl > symsiz) && (!rflag)) { pperror2S("%s: macro recursion",sp->name); return(p); } else { } } else { maclvl = 0; } /* Level decreased. */ macforw = p; /* New target for decrease in level. */ macdam = 0; macnam = sp->name; dump(); #define PROGRESSION_DE_vp \ { \ while (*vp++) \ { \ } \ } \ /* Introduit le 20071122133326 pour resoudre le probleme des caracteres "exotiques" sur */ \ /* '$LACT28'... */ if (sp == ulnloc) { vp = acttxt; *vp++ = Cnull; if (decalage_de__LINE__ >= 0) { sprintf(vp,"%d",lineno[ifno] - ((ifno == IFNO) ? (decalage_de__LINE__) : (0))); /* Le fait que le decalage ne soit applique que sur le premier fichier ('IFNO') a ete */ /* introduit le 20000831150255. */ } else { sprintf(vp,"%d",0); /* Si cette valeur est negative, cela signifie qu'en fait le numero de ligne est indefini, */ /* c'est-a-dire en general trop difficile a determiner (introduit le 20000720115851 a cause */ /* de 'v $xcc/cpp$Z 20000720115851'). On notera que j'aurai prefere editer 'INDEFINI', mais */ /* la valeur de '__LINE__' est editee avec un format entier ("%d"), d'ou cette valeur... */ } PROGRESSION_DE_vp } else { if (sp == uflloc) { vp = acttxt; *vp++ = Cnull; sprintf(vp,"\"%s\"",fnames[ifno]); PROGRESSION_DE_vp } else { if (sp == ufrloc) { int l_fichier = strlen(fnames[ifno]); int l_directory = strlen(dirs[1]); int l_coincidence = strspn(dirs[1],fnames[ifno]); vp = acttxt; *vp++ = Cnull; if ((l_coincidence != l_directory) || (l_fichier < l_directory)) { sprintf(vp,"\"%s\"",fnames[ifno]); /* Lorsque le nom du fichier ne contient pas le nom du premier directory, __FILER__ */ /* equivaut a __FILE__. */ } else { sprintf(vp,"\"%s\"",fnames[ifno]+l_directory+1); /* Par cette translation, on enleve le nom du premier directory defini par '-I'. */ } PROGRESSION_DE_vp } else { if (sp == udiloc) { vp = acttxt; *vp++ = Cnull; sprintf(vp,"\"%s\"",dirnams[ifno]); PROGRESSION_DE_vp } else { if (sp == udeloc) { vp = acttxt; *vp++ = Cnull; sprintf(vp,"\"%s\"",Ndefine->name); PROGRESSION_DE_vp } else { if (sp == umaloc) { vp = acttxt; *vp++ = Cnull; sprintf(vp,"\"%s\"",Nmacro->name); PROGRESSION_DE_vp } else { if (sp == uzero__A__loc) { compteur__A__ = 0; /* Remise a 0 du compteur sans edition... */ vp = acttxt; *vp++ = Cnull; sprintf(vp,"%s",""); /* L'ecriture d'une chaine vide a ete introduite le 20071123092259 pour eliminer les */ /* caracteres "exotiques" sur '$LACT18'... */ PROGRESSION_DE_vp } else { if (sp == uun__A__loc) { compteur__A__ = 1; /* Remise a 1 du compteur sans edition... */ vp = acttxt; *vp++ = Cnull; sprintf(vp,"%s",""); /* L'ecriture d'une chaine vide a ete introduite le 20071123092259 pour eliminer les */ /* caracteres "exotiques" sur '$LACT18'... */ PROGRESSION_DE_vp } else { if (sp == uplus1__A__loc) { compteur__A__++; /* Progression du compteur sans edition... */ vp = acttxt; *vp++ = Cnull; sprintf(vp,"%s",""); /* L'ecriture d'une chaine vide a ete introduite le 20071123092259 pour eliminer les */ /* caracteres "exotiques" sur '$LACT18'... */ PROGRESSION_DE_vp } else { if (sp == umoins1__A__loc) { compteur__A__--; /* Degression du compteur sans edition... */ vp = acttxt; *vp++ = Cnull; sprintf(vp,"%s",""); /* L'ecriture d'une chaine vide a ete introduite le 20071123092259 pour eliminer les */ /* caracteres "exotiques" sur '$LACT18'... */ PROGRESSION_DE_vp } else { if (sp == ucompteur__A__loc) { vp = acttxt; *vp++ = Cnull; sprintf(vp,"%d",compteur__A__); /* Edition du compteur... */ PROGRESSION_DE_vp } else { if (sp == ucompteur__A__8loc) { vp = acttxt; *vp++ = Cnull; sprintf(vp,"%08d",compteur__A__); /* Edition du compteur sur 8 chiffres avec suffisamment de "0"s en tete. Ceci fut introduit */ /* le 20071112105934 afin de generer des compteurs de longueur fixe... */ PROGRESSION_DE_vp } else { if (sp == uzero__B__loc) { compteur__B__ = 0; /* Remise a 0 du compteur sans edition... */ vp = acttxt; *vp++ = Cnull; sprintf(vp,"%s",""); /* L'ecriture d'une chaine vide a ete introduite le 20071123092259 pour eliminer les */ /* caracteres "exotiques" sur '$LACT18'... */ PROGRESSION_DE_vp } else { if (sp == uun__B__loc) { compteur__B__ = 1; /* Remise a 1 du compteur sans edition... */ vp = acttxt; *vp++ = Cnull; sprintf(vp,"%s",""); /* L'ecriture d'une chaine vide a ete introduite le 20071123092259 pour eliminer les */ /* caracteres "exotiques" sur '$LACT18'... */ PROGRESSION_DE_vp } else { if (sp == uplus1__B__loc) { compteur__B__++; /* Progression du compteur sans edition... */ vp = acttxt; *vp++ = Cnull; sprintf(vp,"%s",""); /* L'ecriture d'une chaine vide a ete introduite le 20071123092259 pour eliminer les */ /* caracteres "exotiques" sur '$LACT18'... */ PROGRESSION_DE_vp } else { if (sp == umoins1__B__loc) { compteur__B__--; /* Degression du compteur sans edition... */ vp = acttxt; *vp++ = Cnull; sprintf(vp,"%s",""); /* L'ecriture d'une chaine vide a ete introduite le 20071123092259 pour eliminer les */ /* caracteres "exotiques" sur '$LACT18'... */ PROGRESSION_DE_vp } else { if (sp == ucompteur__B__loc) { vp = acttxt; *vp++ = Cnull; sprintf(vp,"%d",compteur__B__); /* Edition du compteur... */ PROGRESSION_DE_vp } else { if (sp == ucompteur__B__8loc) { vp = acttxt; *vp++ = Cnull; sprintf(vp,"%08d",compteur__B__); /* Edition du compteur sur 8 chiffres avec suffisamment de "0"s en tete. Ceci fut introduit */ /* le 20071112105934 afin de generer des compteurs de longueur fixe... */ PROGRESSION_DE_vp } else { if (sp == Nnew_line) { vp = acttxt; *vp++ = Cnull; sprintf(vp,"\n"); PROGRESSION_DE_vp } else { } } } } } } } } } } } } } } } } } } } if (0 != (params = *--vp & cCHAR(0xFF))) /* Definition calls for params. */ { REGISTER CHAR **pa; Nmacro = sp; /* Lors de la prochaine reference a __MACRO__ c'est le nom courant reference que l'on */ /* recuperera, mais ATTENTION, ce n'est pas recursif... */ save_params = params-1; /* Afin de savoir s'il y a eu des arguments ou '()'... */ /* ici, 'params' donne le nombre d'arguments attendus, a chaque fois qu'a l'appel */ /* de la macro courante un argument est recupere, on decremente 'params' d'une */ /* unite. A la fin, 'params' donne donc la difference entre le nombre d'arguments */ /* attendus et le nombre de celui que l'on a trouve. 'save_params' donne en permanence */ /* le nombre d'arguments-1 ou 254 si la procedure est du type F(). */ /* */ /* DEFINITION : APPEL : params : save_params : */ /* */ /* F() F() 1 254 */ /* F() F 1 254 */ /* F(x) F 1 0 */ /* F(x) F(a) 0 0 */ /* F(x,y,z) F(a,b,c,d,e) 2 2 */ /* */ /* save_params = <arguments dans la definition> - 1 */ /* params = <arguments dans la definition> - <arguments a l'appel> */ /* */ /* <arguments dans la definition> = save_params + 1 */ /* <arguments a l'appel> = save_params + 1 - params */ /* */ ca = acttxt; pa = actual; if (params == cCHAR(0xFF)) { /* #define foo()... */ params = 1; } else { } sloscan(); ++flslvl; /* No expansion during search for actuals. */ plvl = -1; maclin = lineno[ifno]; macfil = fnames[ifno]; do { p = skipbl(p); } while (*inp == '\n'); /* Skip \n too. */ if (*inp == '(') { for (plvl = 1 ; plvl != 0 ; ) { *ca++ = Cnull; for (;;) { outp = inp = p; p = cotoken(p); if (*inp == '(') { ++plvl; } else { } if ((*inp == ')') && (--plvl == 0)) { --params; break; } else { } if ((plvl == 1) && (*inp == ',')) { --params; break; } else { } while (inp < p) { /* Toss newlines in arguments to macros - keep problems to a minimum. */ /* if a backslash is just before the newline, assume it is in a string and leave it in. */ if ((*inp == '\n') && (inp[-1] != SUITE)) { if (1) /* Le 20000619160056, j'ai donc rajoute cette condition destinee a tenter de traiter */ /* des cas du type : */ /* */ /* macro( */ /* #define SYMBOLE VALEUR */ /* #include FICHIER */ /* ) */ /* */ /* ou le fichier 'FICHIER' peut meme utiliser le symbole 'SYMBOLE'... */ /* */ /* le '(0)' permet de sauter la suppression des "newlines", et '(1)' permet de la */ /* reactiver... En fait, cela semble quasiment impossible a utiliser ; en effet, si les */ /* "newlines" sont conserves (ce qui permet de traiter le cas donne en exemple ci-dessus), */ /* on se retrouve, d'un autre cote, avec des lignes "deconcatenees". C'est par exemple le */ /* cas de 'v $ximcf/iterations$DEF choix_du_taux_de_croissance_dans_l_espace_de_Lyapunov' */ /* ou les '=define' se retrouvent sur deux lignes differentes (le nom du symbole sur la */ /* premiere et sa valeur sur la seconde) sans qu'il y ait de code de suite ('\\')... */ /* */ /* On notera que ces newlines semblent etre ceux qui peuvent figuree apres chaque "actual" */ /* lors de l'appel d'une macro. Si le test precedent est desactive par '(0)', soit, par */ /* exemple, la macro suivante : */ /* */ /* #define macro(argument1,argument2) f(argument1) f(argument2) */ /* */ /* si elle est appelee par : */ /* */ /* macro(argument1,argument2) */ /* */ /* cela donnera : */ /* */ /* f(argument1) f(argument2) */ /* */ /* alors que l'appel : */ /* */ /* macro(argument1 */ /* ,argument2 */ /* ) */ /* donnera : */ /* */ /* f(argument1 */ /* ) f(argument2 */ /* ) */ /* */ /* il y ainsi derriere chaque 'argumentI' un newline (ce comportement semble etre celui des */ /* '/usr/lib/cpp' standards). Enfin, si le test precedent est active par '(1)', l'appel */ /* precedent donnera : */ /* */ /* f(argument1 ) f(argument2 ) */ /* */ /* ou donc les newlines ont ete remplaces par des espaces... */ /* */ /* Ainsi, il y a incompatibilite entre le besoin de conserver les newlines (afin de */ /* maintenir '#define SYMBOLE VALEUR' et '#include FICHIER' sur deux lignes bien */ /* differentes, permettant donc leur interpretation en tant que lignes de controle) et */ /* celui de les supprimer afin que des lignes logiques ne se retrouvent pas decoupees */ /* en plusieurs lignes physiques sans code de suite (comme, par exemple ci-dessus, la */ /* ligne logique 'f(argument1)' qui donne deux lignes physiques 'f(argument1' et ')...'). */ { *inp = ' '; /* Le 20000621141005, j'ai essaye de rendre conditionnel ce remplacement des newlines par */ /* des espaces grace a : */ /* */ /* if (inp[+1] == var_SALT) */ /* { */ /* } */ /* else */ /* { */ /* *inp = ' '; */ /* } */ /* */ /* Cela donnait les resultats attendus, sauf lors de '$xcc/Lincludes$Z' sur le fichier */ /* '$xrk/rdn_walk.52$K' qui donnait le message : */ /* */ /* Error : 3983: 'undef' d'un symbole ('gINT_EQUA_DIFF_O1') non defini */ /* */ /* lors de 'v $xcc/Lincludes$Z -k.Us'. Cela semble venir du fait que la directive : */ /* */ /* #define gINT_EQUA_DIFF_O1(cx,cy,cz,t,h) \ */ /* gINTEGRATION_D_UN_SYSTEME_...(cx,cy,cz,t,h) */ /* */ /* n'est plus interpretee comme un '#define', ce qui justifie le message lors du '#undef' */ /* correspondant... */ } else { } } else { } *ca++ = *inp++; } if (ca > &acttxt[eBUFSIZ]) { pperror2S("%s: actuals too long",sp->name); } else { } } if (pa >= &actual[MAXFRM]) { ppwarn(match,sp->name); } else { *pa++ = ca; } } } else { if (var_warning == 0) { ppwarn(match3,sp->name); } else { ++plvl ; if (bob(p)) { outp = inp = p; p = unfill(p); } else { } *--p = var_SALT; *--p = var_SALT; *--p = var_SALT; *--p = var_SALT; /* ATTENTION : je mets dorenavant huit caracteres 'var_SALT' afin de limiter des problemes */ /* avec des fichiers tels '$xiida/fonction$FON' qui contiennent des chaines du type '%%%%'. */ /* Cette sequence de huit caracteres 'var_SALT' est reprise ensuite par le fichier suivant */ /* '$xcc/cpp$D/fARGUMENT$sed'... */ *--p = var_SALT; *--p = var_SALT; *--p = var_SALT; *--p = var_SALT; /* *--p = ' '; ATTENTION : je supprime le caractere ' ' a cause de 'op_structure$X' */ } /* JF. COLONNA. */ } if (maclin != lineno[ifno]) /* Embedded linefeeds in macro call. */ { int i,j = lineno[ifno]; for (i = sizeof(int) / sizeof(CHAR) ; --i >= 0 ; ) { if (bob(p)) { outp = inp = p; p = unfill(p); } else { } *--p = j; j >>= 8; } if (bob(p)) { outp = inp = p; p = unfill(p); } else { } *--p = warnc; } else { } if (params != 0) { if (params > 0) { if ((save_params != params) && ((save_params+1-params) != 0)) { ppwarn(match1,sp->name); /* Cas : pas assez d'arguments (mais au moins 1 est present a l'appel...). */ } else { if (var_warning == 0) { ppwarn(match4,sp->name); } else { if (bob(p)) { outp = inp = p; p = unfill(p); } else { } *--p = var_SALT; *--p = var_SALT; *--p = var_SALT; *--p = var_SALT; /* ATTENTION : je mets dorenavant huit caracteres 'var_SALT' afin de limiter des problemes */ /* avec des fichiers tels '$xiida/fonction$FON' qui contiennent des chaines du type '%%%%'. */ /* Cette sequence de huit caracteres 'var_SALT' est reprise ensuite par le fichier suivant */ /* '$xcc/cpp$D/fARGUMENT$sed'... */ *--p = var_SALT; *--p = var_SALT; *--p = var_SALT; *--p = var_SALT; *--p = ' '; } /* JF. COLONNA. */ } } else { } } else { } if (params < 0) { ppwarn(match2,sp->name); /* Cas : trop d'arguments... */ } else { } while (--params >= 0) { *pa++ = fCHAR("")+1; /* Null string for missing actuals. */ } --flslvl; fasscan(); } else { } for (;;) /* Push definition onto front of input stack. */ { while (!iswarn(*--vp)) { if (bob(p)) { outp = inp = p; p = unfill(p); } else { } *--p = *vp; /* Je note le 20060509112157 que c'est dans cette boucle que les caracteres definissant */ /* la macro courante sont transferes, mais ATTENTION : en allant du dernier au premier... */ } if (*vp == warnc) /* Insert actual param. */ { ca = actual[*--vp - 1]; while (*--ca) { if (bob(p)) { outp = inp = p; p = unfill(p); } else { } *--p = *ca; } } else { break; } } outp = inp = p; return(p); } CHAR *trmdir(s) REGISTER CHAR *s; { REGISTER CHAR *p = s; while (*p++) { } --p; while ((p > s) && (*--p != '/')) { } if (p == s) { *p++ = '.'; } else { } *p = Cnull; return(s); } STATIC CHAR *copy(s) REGISTER CHAR *s; { REGISTER CHAR *old; old = savch; while (*savch++ = *s++) { } return(old); } yywrap() { return(1); } main(argc,argv) CHAR *argv[]; { REGISTER int i,c; REGISTER CHAR *p; CHAR *tf,**cp2; fin = stdin; fout = stdout; /* Mis ici le 20071121175228 a cause de '$LACT18' et de 'SYSTEME_APC_LinuxUbuntu_GCC'... */ #ifdef ALLOCATION_STATIQUE #else ALLOCATION_STATIQUE for (i = 1 ; i < argc ; i++) /* Il est essentiel de gerer les options "-B" et "-b" avant tout autre chose puisque, */ /* ensuite, les zones allouees dynamiquement seront tres rapidement necessaires... */ { switch (argv[i][0]) { case '-': switch (argv[i][1]) { case 'B': dBUFSIZ = atoi(&argv[i][2]); /* Pour dimensionner dynamiquement 'buffer' (introduit le 20210228093631). */ /* */ /* Le 20210301173354, on notera que par defaut : */ /* */ /* dBUFSIZ = BUFSIZ */ /* = 1024*4096 */ /* = 4194304 */ /* */ continue; case 'b': dSBSIZE = atoi(&argv[i][2]); /* Pour dimensionner dynamiquement 'sbf' (introduit le 20210228093631). */ /* */ /* Le 20210301173354, on notera que par defaut : */ /* */ /* dSBSIZE = SBSIZE */ /* = 50000000 */ /* */ continue; default: continue; } default: continue; } } buffer = malloc(dLbuffer); sbf = malloc(dSBSIZE); savch = sbf; /* Le dimensionnement dynamique de 'buffer' et 'sbf' a ete introduit le 20210228093631... */ /* On notera le 20210301122625 que la mise a zero de 'buffer' et de 'sbf' ne semble pas */ /* utile. Il en est de meme pour la contiguite de 'buffer' et 'sbf'... */ # define NETTOYAGE_ALLOCATION_DYNAMIQUE 0 /* Deux valeurs possibles : */ /* */ /* 0 : pas de nettoyage, */ /* 1 : nettoyage... */ /* */ /* Le 20210304102609, le nettoyage des zones allouees dynamiquement a ete inhibe puisque */ /* d'une part il est penalisant et que d'autre part il semble ne servir a rien... */ if (NETTOYAGE_ALLOCATION_DYNAMIQUE) { for (i = 0 ; i < dLbuffer ; i++) { *(buffer+i) = NULL; /* Le 20210301171608, malgre les commentaires precedents, le 'buffer' alloue est nettoye... */ } for (i = 0 ; i < dSBSIZE ; i++) { *(sbf+i) = NULL; /* Le 20210301171608, malgre les commentaires precedents, le 'sbf' alloue est nettoye... */ } } else { } #endif ALLOCATION_STATIQUE for (i = 0 ; i < symsiz ; i++) { stab[i].name = NULL; stab[i].value = NULL; /* Le 19970704181453, j'ai introduit l'initialisation de la table des symboles a cause de */ /* la nouvelle option '-S' qui permet de lister les symboles a la fin... */ } p = fCHAR("_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789(,)"); while (c = *p++) { (fastab+COFF)[c] |= AB; /* Introduit le 20190120101149 afin de permettre d'utiliser l'option "-D" avec des */ /* procedures avec "Arguments" et par exemple : */ /* */ /* -D"fonction(a,b)=(a+b)" */ /* */ } p = fCHAR("_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); for (i = 1 ; i < argc ; i++) { switch (argv[i][0]) { case '-': switch (argv[i][1]) { case 'A': /* Option "-A" (pour 'Alphabet etendu'). */ p = fCHAR("_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$"); /* Le 19970221090012, le caractere "$" a ete ajoute comme caractere possible pour le nom */ /* d'un identifieur (et ceci a cause de '$xcc/Lincludes$Z'). Mais ceci est une option car, */ /* en effet, le caractere '$' est deja utilise ('v $xrq/particle.M1$I f_racine_Fsequence'). */ continue; default: continue; } default: continue; } } i = 0; while (c = *p++) { (fastab+COFF)[c] |= IB | NB | SB; (toktyp+COFF)[c] = IDENT; #if scw2 /* 53 == 63-10; digits rarely appear in identifiers, */ /* and can never be the first char of an identifier. */ /* 11 == 53*53/sizeof(macbit) . */ ++i; (t21+COFF)[c] = (53*i)/11; (t22+COFF)[c] = i%11; #else scw2 #endif scw2 } p = fCHAR("0123456789."); while (c = *p++) { (fastab+COFF)[c] |= NB | SB; (toktyp+COFF)[c] = NUMBR; } p = fCHAR("\n\"'/\\"); while (c = *p++) { (fastab+COFF)[c] |= SB; } p = fCHAR("\n\"'\\"); while (c = *p++) { (fastab+COFF)[c] |= QB; } p = fCHAR("*\n"); while (c = *p++) { (fastab+COFF)[c] |= CB; } (fastab+COFF)[warnc] |= WB | SB; (fastab+COFF)[Cnull] |= CB | QB | SB | WB; for (i = ALFSIZ ; --i >= 0 ; ) { slotab[i] = fastab[i] | SB; } p = fCHAR(" \t\v\f\r"); /* Note no \n. */ while (c = *p++) { (toktyp+COFF)[c] = BLANK; } #if scw2 for ((t23+COFF)[i = ALFSIZ+7-COFF] = 1 ; --i >= -COFF ; ) { if (((t23+COFF)[i] = (t23+COFF 1)[i] << 1) == 0) { (t23+COFF)[i] = 1; } else { } } #else scw2 #endif scw2 fnames[ifno = IFNO] = fCHAR(""); dirnams[0] = dirs[0] = fCHAR("."); for (i = 1 ; i < argc ; i++) { switch (argv[i][0]) { case '-': switch (argv[i][1]) { case 'L': ShowIncludes++; continue; /* Pour indiquer au fur et a mesure les 'include's executes (introduit le 20101214162107). */ case 'S': Showdefines++; continue; /* Pour lister a la fin la liste des '#define'... */ case 'A': /* Option "-A" (pour 'Alphabet etendu') : rien a faire, elle a deja ete traitee... */ continue; case 'w': var_warning++; continue; /* Pour inhiber les warnings sur les macros f(...) sans leurs arguments d'appels. */ case 'u': uflag++; continue; /* Pour inhiber les messages d'erreur du type : */ /* */ /* Error : ...: undef symbol ... in preprocessor if */ /* */ case 'c': var_SALT = argv[i][2]; /* Changement du caractere d'introduction des commandes a 'cpp' (John F. COLONNA). */ continue; case 'k': var_CONC = argv[i][2]; /* Changement du caractere de concatenation substitue a 'var_SALT' (John F. COLONNA). */ continue; case 'e': var_EXTE = argv[i][2]; /* Changement du caractere d'introduction des commandes non reconnues et reinserees... */ continue; case 'd': traiter_les_defines = 1; /* Permet de transmettre integralement les defines (de meme que les "un-defines") au fichier */ /* "out" sans les traiter ; par contre toutes les autres directives seront bien executees... */ continue; case 'i': traiter_les_ifs_elses_endifs = 1; /* Permet de transmettre integralement les {if,else,endif}s au fichier "out" sans les */ /* traiter ; par contre toutes les autres directives seront bien executees (ceci fut */ /* introduit le 20101214185905). */ continue; case 'm': traiter_les_messages = 1; /* Permet de transmettre integralement les messages au fichier "out" sans les traiter... */ continue; case 'X': traiter_les_systems = 1; /* Permet de transmettre integralement les system's au fichier "out" sans les traiter... . */ continue; case 't': TransmettreControlesNonReconnus = 1; /* Permet de transmettre "betement" les controles non reconnus ('pragma' par exemple). Ceci */ /* fut introduit le 20101214181121... */ continue; case 'l': decalage_de__LINE__ = atoi(&argv[i][2]); /* Pour decaler eventuellement la variable '__LINE__' (introduit le 20000512114908). */ continue; case 'P': pflag++; case 'E': continue; case 'R': ++rflag; continue; case 'C': passcom++; continue; case 'D': if (predef > prespc+NPREDEF) /* ATTENTION, il y avait avant : */ /* */ /* #define NPREDEF 20 */ /* */ /* mais les tests "trop de "-D" et "trop de -U" ne marchent pas, ce qui a ete mis en */ /* evidence dans '$xcc/cpp$Z' lorsque le nombre de defines par "-D" a atteint 21 lors du */ /* remplacement de l'option 'inclure_DEFINIT_cK_DEF' par le couple 'inclure_DEFINIT_c_DEF' */ /* et 'inclure_DEFINIT_K_DEF'... */ { pperror2S("too many -D options, ignoring %s",argv[i]); continue; } else { } /* Ignore plain "-D" (no argument). */ if (*(argv[i]+2)) { *predef++ = argv[i]+2; } else { } continue; case 'U': if (prund > punspc+NPREDEF) /* ATTENTION, il y avait avant : */ /* */ /* #define NPREDEF 20 */ /* */ /* mais les tests "trop de "-D" et "trop de -U" ne marchent pas, ce qui a ete mis en */ /* evidence dans '$xcc/cpp$Z' lorsque le nombre de defines par "-D" a atteint 21 lors du */ /* remplacement de l'option 'inclure_DEFINIT_cK_DEF' par le couple 'inclure_DEFINIT_c_DEF' */ /* et 'inclure_DEFINIT_K_DEF'... */ { pperror2S("too many -U options, ignoring %s",argv[i]); continue; } else { } *prund++ = argv[i]+2; continue; case 'I': if (nd > MAXINC-4) { pperror2S("excessive -I file (%s) ignored",argv[i]); } else { dirs[nd++] = argv[i]+2; } continue; #ifdef ALLOCATION_STATIQUE #else ALLOCATION_STATIQUE case 'B': /* Cet argument a deja ete traite au tout debut du 'main(...)' mais doit de nouveau etre */ /* teste ici afin d'eviter le message : */ /* */ /* Error : 0: unknown flag */ /* */ continue; case 'b': /* Cet argument a deja ete traite au tout debut du 'main(...)' mais doit de nouveau etre */ /* teste ici afin d'eviter le message : */ /* */ /* Error : 0: unknown flag */ /* */ continue; #endif ALLOCATION_STATIQUE case Cnull: continue; default: pperror2S("unknown flag %s",argv[i]); continue; } default: if (fin == stdin) { if (NULL == (fin = fopen(argv[i],READ))) { pperror2S("No source file %s",argv[i]); exit(RETURN_8); } else { } fnames[ifno] = copy(argv[i]); dirs[0] = dirnams[ifno] = trmdir(argv[i]); /* Too dangerous to have file name in same syntactic position */ /* be input or output file depending on file redirections, */ /* so force output to stdout, willy-nilly */ /* [i don't see what the problem is. jfr]. */ } else { if (fout == stdout) { #ifdef ALLOCATION_STATIQUE static CHAR _sobuf[eBUFSIZ]; #else ALLOCATION_STATIQUE static CHAR *_sobuf; _sobuf = malloc(eBUFSIZ); if (NETTOYAGE_ALLOCATION_DYNAMIQUE) { for (i = 0 ; i < dLbuffer ; i++) { *(_sobuf+i) = NULL; /* Introduit le 20210304102609... */ } } else { } #endif ALLOCATION_STATIQUE if (NULL == (fout = fopen(argv[i],WRITE))) { pperror2S("Can't create %s",argv[i]); exit(RETURN_8); } else { fclose(stdout); setbuf(fout,_sobuf); } } else { pperror2S("extraneous name %s",argv[i]); } } } } fins[ifno] = fin; exfail = 0; /* After user -I files here are the standard include libraries. */ dirs[nd++] = fCHAR("/usr/include"); dirs[nd++] = 0; /* */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * ** * * * * * ** * */ /* * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * */ /* * * * * ** * * * * * ** */ /* * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* */ /* ATTENTION : */ /* */ /* Lorsque de nouvelles directives sont */ /* introduites ici, il peut etre necessaire */ /* de modifier les fichiers de '$xcc/cpp$D' */ /* de meme que la commande '$xi/DICO_define$Z' */ /* en consequences... */ /* */ /* */ DefDirectives=0; /* Introduit le 20090913183034 afin de savoir que la definition des directives commence. */ defloc = ppsym("define"); defmloc = ppsym("mdefine"); /* Identique a 'define' avec possibilite de redefinir un symbole pre-existant (et qui */ /* peut ne pas pre-exister) d'ou le nom "Multiple define". Ceci fut introduit le */ /* 20090929165309... */ redefloc = ppsym("redefine"); /* Identique a 'define' avec possibilite de redefinir un symbole pre-existant (et qui */ /* doit pre-exister a compter du 20090913183034...). */ tdefloc = ppsym("TestADef"); /* Identique a 'define' sauf que la definition n'est faite, que si le symbole ne pre-existe */ /* pas, d'ou le nom 'test and define'. On peut dire aussi que : */ /* */ /* #TestADef SYMBOLE VALEUR */ /* */ /* equivaut a : */ /* */ /* #ifndef SYMBOLE */ /* # define SYMBOLE VALEUR */ /* #Aifndef SYMBOLE */ /* #Eifndef SYMBOLE */ /* */ Defloc = ppsym("define"); /* Identique a 'define' mais ne peut etre transmise au fichier "out' (voir l'indicateur */ /* 'traiter_les_defines' ; lorsque ce dernier est different de 0 -option "d"-, les */ /* 'define' sont transmis integralement sur 'out' alors que les 'define' ne le sont pas). */ udfloc = ppsym("undef"); Udfloc = ppsym("Undef"); /* Identique a 'undef', mais sans erreur pour un 'Undef' d'un symbole non defini. */ nodefloc = ppsym("nodefine"); /* Identique a 'undef', mais sans erreur si le symbole est non defini, */ /* est en fait introduit pour remplacer la suite '#define xx''#undef xx' pour les */ /* options, les '_VERSION_' ou encore le 'BUG's... */ notdefloc= ppsym("nTestADef"); /* Identique a 'undef', mais sans erreur si le symbole est non defini, par symetrie avec */ /* 'TestADef'... */ nydefloc = ppsym("nydefine"); /* Identique a 'undef', mais sans erreur si le symbole est non defini, */ /* est en fait introduit pour "marquer" des definitions pas encore faites ("Not Yet..."), */ /* ou encore pas tout a fait correctes ('v $xig/fonct$vv$DEF 20070819132949'). */ incloc = ppsym("include"); Eincloc = ppsym("Einclude"); /* Identique a 'include' mais sans erreur si le fichier n'existe pas. */ Wincloc = ppsym("Winclude"); /* Identique a 'include' mais avec attente de deverouillage (introduit le 20161213144856). */ mesloc = ppsym("message"); warloc = ppsym("warning"); /* Synonyme de 'message' rendu necessaire parce que tres utilise sur '$LACT1B' (introduit */ /* le 20210903175906)... */ sysloc = ppsym("system"); ifloc = ppsym("if"); Aifloc = ppsym("Aif"); elsloc = ppsym("else"); elsiloc = ppsym("elseif"); Eifloc = ppsym("Eif"); eifloc = ppsym("endif"); ifdloc = ppsym("ifdef"); Aifdloc = ppsym("Aifdef"); elsdloc = ppsym("elseifdef"); Eifdloc = ppsym("Eifdef"); eifdloc = ppsym("endifdef"); ifnloc = ppsym("ifndef"); Aifndloc = ppsym("Aifndef"); elsndloc = ppsym("elseifndef"); Eifndloc = ppsym("Eifndef"); eifndloc = ppsym("endifndef"); lneloc = ppsym("line"); clsloc = ppsym("class"); DefDirectives=1; /* Introduit le 20090913183034 afin de savoir que la definition des directives est achevee. */ /* */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * ** * * * * * ** * */ /* * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * */ /* * * * * ** * * * * * ** */ /* * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* */ /* ATTENTION : */ /* */ /* Lorsque de nouvelles directives sont */ /* introduites ici, il peut etre necessaire */ /* de modifier les fichiers de '$xcc/cpp$D' */ /* en consequences... */ /* */ /* */ for (i = sizeof(macbit) / sizeof(macbit[0]) ; --i >= 0 ; ) { macbit[i] = 0; } ysysloc = stsym("unix"); /* Ca y est j'ai compris la presence des definitions qui suivent : c'est a cause des */ /* includes systemes du type 'stdio.h' qui font des '#if' sur les variables 'ridge',... */ /* pour generer des structures du type 'FILE'. Il faut donc maintenir ces definitions... */ #if ridge varloc = stsym("ridge"); #else ridge #endif ridge tf = fnames[ifno]; fnames[ifno] = fCHAR("command line"); lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ ulnloc = stsym("__LINE__"); lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ Nnew_line = stsym("__NEW_LINE__"); lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ uflloc = stsym("__FILE__"); lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ ufrloc = stsym("__FILER__"); /* Identique a '__FILE__', mais en supprimant le debut suppose correspondre au */ /* premier directory defini par '-I'... */ lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ udiloc = stsym("__DIRECTORY__"); lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ udeloc = stsym("__DEFINE__"); lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ Ndefine = stsym("dEMPTY"); /* Afin d'initialiser le nom courant a dEMPTY (on ne peut utiliser "" car en effet */ /* 'stsym' le refuse... */ umaloc = stsym("__MACRO__"); lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ Nmacro = stsym("mEMPTY"); /* Afin d'initialiser le nom courant a mEMPTY (on ne peut utiliser "" car en effet */ /* 'stsym' le refuse... */ lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ uzero__A__loc = stsym("__ZERO__A__"); lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ uun__A__loc = stsym("__UN__A__"); lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ uplus1__A__loc = stsym("__PLUS1__A__"); lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ umoins1__A__loc = stsym("__MOINS1__A__"); lineno[ifno] = 0; /* Au cas ou il y aurait des problemes dans les 'stsym' qui suivent... */ ucompteur__A__loc = stsym("__COMPTEUR__A__"); ucompteur__A__8loc = stsym("__COMPTEUR8__A__"); /* Le compteur sur 8 chiffres a ete introduit le 20071112105934 afin de generer des */ /* compteurs de longueur fixe... */ compteur__A__=0; /* A priori, on initialise le simulateur de compteur a 0. */ /* */ /* Ce compteur est initialise a 0 par '__ZERO__A__' et a 1 par '__UN__A__', et peut */ /* etre reference par '__PLUS1__A__' qui de plus l'incremente d'une unite apres usage, */ /* et par '__MOINS1__A__' qui de plus le decremente d'une unite avant usage. */ /* */ /* Le 20060208095656, l'utilisation de "compteur" a change ; les symboles precedents */ /* {__ZERO__A__,__UN__A__,__PLUS1__A__,__MOINS1__A__} ne font que modifier sa valeur. Mais */ /* dorenavant, sa valeur n'est utilisee et editee que via '__COMPTEUR__A__'. Ceci a ete */ /* introduit pour 'v $xig/fonct$vv$DEF 20060208101231'. En fait, il aurait ete plus simple */ /* d'introduite un symbole du type '__PROFONDEUR__' incremente d'une unite d'une unite */ /* lors de l'entree dans une procedure et decremente d'une unite a la sortie. */ /* Malheureusement, les tests effectues au niveau du 'subst(...)' contenu dans */ /* 'slookup(...)' ont montre que les choses de fonctionnait pas ainsi ; la substitution */ /* n'est pas recursive. Ainsi le code suivant : */ /* */ /* #define proc1(arg1) arg1 */ /* #define proc2(arg2) arg2 */ /* proc2(proc1(arg)) */ /* */ /* donne naissance a une premiere reecriture : */ /* */ /* proc1(arg) ---> arg */ /* */ /* sans que finalement 'proc2(...)' soit en quelque sorte en attente, puis ensuite a */ /* une seconde reecriture : */ /* */ /* proc2(arg) ---> arg */ /* */ uzero__B__loc = stsym("__ZERO__B__"); lineno[ifno] = 0; uun__B__loc = stsym("__UN__B__"); lineno[ifno] = 0; uplus1__B__loc = stsym("__PLUS1__B__"); lineno[ifno] = 0; umoins1__B__loc = stsym("__MOINS1__B__"); lineno[ifno] = 0; ucompteur__B__loc = stsym("__COMPTEUR__B__"); ucompteur__B__8loc = stsym("__COMPTEUR8__B__"); compteur__B__=0; /* Le deuxieme compteur a ete introduit le 20190831104916... */ lineno[ifno] = 1; cp2 = prespc; while (cp2 < predef) { stsym(*cp2++); } cp2 = punspc; while (cp2 < prund) { if (p = strchr(*cp2,'=')) { *p++ = Cnull; } else { } lookup(*cp2++,DROP); } fnames[ifno] = tf; pbeg = buffer+NCPS; pbuf = pbeg+eBUFSIZ; pend = pbuf+eBUFSIZ; trulvl = 0; flslvl = 0; lineno[0] = 1; sayline(); outp = inp = pend; control(pend); if (trulvl != 0) { pperror2I(MImbric1" -2-",0); } else { } if (flslvl != 0) { pperror2I(MImbric2" -2-",0); } else { } #undef MImbric1 #undef MImbric2 return((exfail) ? ((exfail == CLASSCODE) ? CLASSCODE : RETURN_2) : RETURN_0); }