/* Copyright (C) 2011-2022 Patrick H. E. Foubet - S.E.R.I.A.N.E. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see *******************************************************************/ /* histo.c */ #include "conf.h" #include #include #include #include #include #include #include #include #include #include #include "histo.h" #include "nife.h" #include "mth.h" #include "err.h" #include "lib.h" #include "debug.h" #define HISTOMAX 100 static char * HIST[HISTOMAX]; static int iH=0, iHt, iHl, iHFull=0; #define FDMAX 128 static int iFD=0; static int FD_T[FDMAX], FD_L[FDMAX]; /* fd table and line numbers */ static void *FD_N[FDMAX]; void IF_showFD(void) { printf("iFD=%d FD_T=%d FD_L=%d\n",iFD, FD_T[iFD], FD_L[iFD]); } void addFD(int fd, char*S) { void *M; iFD++; /* printf("addFD iFD=%d\n",iFD); */ if (iFD == FDMAX) { iFD--; messErr(45); return; } _MODIF_FD_IN_(fd); FD_T[iFD]=fd; FD_L[iFD]=0; if ((M = malloc(strlen(S)+1)) == NULL) stopErr("addFD","malloc"); #ifdef DEBUG_M printf("New String address : %lu \n",(unsigned long)M); #endif strcpy((char*)M,S); FD_N[iFD]=M; } void closeFD(void) { /* printf("closeFD iFD=%d\n",iFD); */ close(FD_IN); free(FD_N[iFD]); iFD--; if (iFD) _MODIF_FD_IN_(FD_T[iFD]); else _MODIF_FD_IN_(0); } int getiFD(void) { return iFD; } int getFDlig(void) { return FD_L[iFD]; } char * getFDname(void) { return (char*)FD_N[iFD]; } void incFDlig(void) { FD_L[iFD]++; } void razHisto(void) { int i; for(i=0;i= s) { *(w+1) = *w; w--; } *s=c; } int lireLigne(int fd, char *b, char *s, int nc) /* fd = file descriptor b = adresse du buffer nc = nb de caracteres possible (longueur du buffer */ { char *d, *f, c, c2, c3, *h, *w, *Wl, *rac; int n, i, l, ls=0, ins=0, ignTild=0, nbT=0, Nc; unsigned int j; char bufd[50]; /* printf("lireLigne ... \n"); */ d = b; f = b+nc; while(d b=<%s>\n",d-b,ins,s,b); */ if ((n=read(fd,d,1)) != 1) break; c=*d; if (ignTild && (c == '~')) { ignTild=0; continue; } if ((c > 31) && (c < 127)) { /* de SPACE a TILDE */ if (!((FD_IN || iTERM) && ECHOOFF)) { printf("%c",c); if (ins) { if (ins==2) /* rewrite */ enleve1(s); if(*s =='\0') ins=0; else { printf("%s",s); for (j=0; jb) { *d='\0'; w=d-1; while ((w>b) && (!(isSepa(*w,1)))) w--; if (isSepa(*w,0)) w++; /* fprintf(stderr,"d-b=%d w=<%s>\n",d-b,w); */ if (strlen(w) > 0) { j=nbLibBegin(w, &rac); /* fprintf(stderr,"j=%d w=<%s>\n",j,w); */ if (j==0) printf("\a"); else { if (j==1) { Wl=getLibBegin(w); i=strlen(Wl)-strlen(w); /* fprintf(stderr,"i=%d Wl=<%s>\n",i,Wl); */ if (i>0) { strcpy(w,Wl); printf("%s ",d); d+=i; *d++ = ' '; if (ins) { printf("%s ",s); for (j=0; j<(strlen(s)+1); j++) printf("\b"); } } else { /* XXXX */ if (i==0) { printf (" "); *d++ = ' '; } } } else { if (rac != NULL) { i=strlen(rac)-strlen(w); strcpy(w,rac); printf("%s",d); d+=i; if (ins) { printf("%s ",s); for (j=0; j<(strlen(s)+1); j++) printf("\b"); } } else { nbT++; if (nbT>1) { nbT=0; printf("\n"); listLibBegin(w); *d='\0'; printf("> %s",b); if (ins) { printf("%s ",s); for (j=0; j<(strlen(s)+1); j++) printf("\b"); } fflush(stdout); } } } } fflush(stdout); } } break; case '\177': if (d>b) { printf("\b \b"); if (ins) { printf("%s ",s); for (j=0; j<(strlen(s)+1); j++) printf("\b"); } fflush(stdout); d--; } break; case '\n': case '\r': if ((FD_IN || iTERM) && ECHOOFF) printf("."); else { printf("\n"); if (ins) { if (d+strlen(s) < f) { sprintf(d,"%s",s); d+=strlen(s); } else return(-1); } } goto finBoucle; /* gestion des caracteres speciaux */ case '\033': /* ESCAPE */ ignTild=1; Nc=read(fd,&c2,1); Nc=read(fd,&c3,1); if (c2 == '[') { /* CSI - see XTerm Control Sequences */ switch(c3) { case '2' : /* Insert */ if (ins) { ins++; if (ins==3) ins=1; } break; case '3' : /* Suppr */ if (ins) { enleve1(s); if(*s =='\0') ins=0; printf("%s \b",s); for (j=0; j */ if (ins) { *d = *s; printf("%c",*d++); enleve1(s); if(*s =='\0') ins=0; else { printf("%s",s); for (j=0; jb) { if (ins==0) { ins=1; *d='\0'; strcpy(s,d-1); } else insertC(*(d-1),s); d--; printf("\b"); fflush(stdout); } break; case 'H' : /* home : debug terms ON */ case '1' : /* home numeric */ IFD_DebugTOn(); break; case 'F' : /* end : debug terms OFF */ case '4' : /* end numeric */ IFD_DebugTOff(); break; default: sprintf(bufd,"# ignore : ESC [ %d (%c) !",(int)c3, c3); D_Tracenl(bufd); *d='\0'; /* ************** printf("> %s",b); fflush(stdout); */ } } else { if (c2 == 'O') { /* SS3 - see XTerm Control Sequences */ switch(c3) { case 'P' : /* F1 */ break; case 'Q' : /* F2 */ break; case 'R' : /* F3 */ break; case 'S' : /* F4 */ break; case 'H' : /* home : debug terms ON */ IFD_DebugTOn(); break; case 'F' : /* end : debug terms OFF */ IFD_DebugTOff(); break; } } else { sprintf(bufd,"# ignore : ESC %d %d (%c) !",(int)c2,(int)c3, c3); D_Tracenl(bufd); *d='\0'; /* ************** printf("> %s",b); fflush(stdout); */ } } break; default : /* printf("\nCar = %d !\n",(int)c); *d='\0'; printf("> %s",b); fflush(stdout); */ break; } } if (ins) ls = strlen(s); } finBoucle: /* printf("fin lireLigne!\n"); */ if ((n<1) && (FD_IN !=0)) { closeFD(); /* fichier loader */ if (ECHOOFF) printf("\n"); return 0; } if ((n<1) && iTERM) { close(FD_IN); /* pipe ou autre */ Nc=dup(iTERM); /* stdin on term */ iTERM = 0; if (ECHOOFF) printf("\n"); return 0; } if (d == f) { /* cas du buffer trop petit */ /* d=b; while (*d != '\n') read(fd,d,1); **** not in raw mode */ #ifdef DEBUG printf("lireLigne : erreur !\n"); #endif return(-1); } *d = '\0'; #ifdef DEBUG printf("lireLigne : retour <%s> !\n",b); #endif if (!FD_IN) putHisto(b); incFDlig(); return(strlen(b)); }