#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "charfilter.h"
#include "alt_unistd.h"
#include "configuration.h"

#ifdef OS_UNIX_ALIKE
#include <unistd.h>
#endif

char *verstring="sap V0.2 beta";

/*

Poniższe procedury uwzględniają specyfikę kolejności
liter w alfabecie polskim oraz ograniczenie dostępnych
znaków

*/

unsigned char _convtable[256],_avtable[256];
#ifndef OS_AMIGAOS
unsigned char *txt1="aąbcćdeęfghijklłmnńoópqrsśtuvwxyzźż*<>'/.,";
unsigned char *txt2="AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ*<>'/.,";
#else
unsigned char *txt1="aąbcćdeęfghijklłmnńoópqrsśtuvwxyzźż*<>'/.,âëîďôűú";
unsigned char *txt2="AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ*<>'/.,ÂËÎĎÔŰÚ";
#endif

int asciionly_mode; /* if true use only base ASCII (<128) chars */

mk_convt(void)
{
    int i;unsigned char *c1,*c2;
    memset(_convtable,0,256); // a tak, na wszelki wypadek
    for (i=0;i<256;i++) _avtable[i]=i;
    for (i=0,c1=txt1,c2=txt2;*c1;c1++,c2++,i++) {
       _convtable[(*c1)&255]=_convtable[(*c2)&255]=i+1;
	_avtable[(*c2)&255]=*c1;
	}
}

is_prt(int c)
{
    return _convtable[c&255];
}

l_tolower(int c)
{
    if (!_convtable[c=(c&255)]) return 0;
    return _avtable[c];
}

l_compare(char *c1,char *c2)
{
     for (;*c1;c1++,c2++) {
         if (!*c2) return 1; // c1>c2;
	 if (_convtable[(*c1)&255]>_convtable[(*c2)&255]) return 1;
	 if (_convtable[(*c1)&255]<_convtable[(*c2)&255]) return -1;
	 }
    if (*c2) return -1;
    return 0;
}

l_match(char *c1,char *c2)
{
     for (;*c1;c1++,c2++) {
         if (!*c2 || *c2=='*') return 0; // c1 match c2;
	 if (_convtable[(*c1)&255]>_convtable[(*c2)&255]) return 1;
	 if (_convtable[(*c1)&255]<_convtable[(*c2)&255]) return -1;
	 }
    if (*c2 && *c2!='*') return -1;
    return 0;
}

l_pmatch(char *c1,char *c2)
{
    for (;;) {
	if (*c2=='*') {
	    while (*c2=='*') c2++;
	    if (!*c2) return 0;
	    while (*c1) if (!l_pmatch(c1++,c2)) return 0;
	    return 1;
	}
	if (*c1!=*c2) return 1;
	if (!*c1) return 0;
	c1++;c2++;
    }
}



struct vobel {
    long npages;
    long nwords;
    long *page_offsets;
    long actual_page;
    long lastpage,lastindex;
    FILE *f;
    char *pairbuffer;
    char **pairs;
    // strona
    short wordspp;
    short dsize;
    short dvoffset;
    short *sizes;
    char *first;
    char body[16384];
} vobel[2];

ReadVobel(char *name,int nr)
{
    char avname[256];
    long v_long,ls,i;char *c;
    if (!(vobel[nr].f=fopen(name,"rb"))) {
	c=getenv("HOME");
	c=NULL;
        if (c) {
	    strcpy(avname,c);
	    strcat(avname,DIRECTORY_SEPARATOR);
	    strcat(avname,name);
	    if (!(vobel[nr].f=fopen(avname,"rb"))) {
		strcpy(avname,DICTIONARIES_DIRECTORY);
		strcat(avname,name);
	        if (!(vobel[nr].f=fopen(avname,"rb"))) exit(100);
	    }
	} else {
		strcpy(avname,DICTIONARIES_DIRECTORY);
		strcat(avname,name);
	        if (!(vobel[nr].f=fopen(avname,"rb"))) exit(100);
	}
    }
    if (!fread(&v_long,sizeof(long),1,vobel[nr].f)) goto zle;
#ifdef MSB_FIRST_PROCESSOR
		lsb2msb(&v_long);
#endif
    if (v_long!=0xFADEABBA) {
	alt_fprintf(asciionly_mode,stderr,"Plik %s nie jest plikiem słownika!\n",avname);
	exit(100);
    }
    if (!fread(&vobel[nr].nwords,sizeof(long),1,vobel[nr].f)) goto zle;
#ifdef MSB_FIRST_PROCESSOR
		lsb2msb(&(vobel[nr].nwords));
#endif
    if (!fread(&vobel[nr].npages,sizeof(long),1,vobel[nr].f)) goto zle;
#ifdef MSB_FIRST_PROCESSOR
		lsb2msb(&(vobel[nr].npages));
#endif
    /* teraz alokujemy tablicę offsetów opisów */
    if (!(vobel[nr].page_offsets=malloc(sizeof(long)*vobel[nr].npages))) goto zle;
    if (!fread(vobel[nr].page_offsets,sizeof(long)*vobel[nr].npages,1,vobel[nr].f)) goto zle;
#ifdef MSB_FIRST_PROCESSOR
	{
		int remaining_longs=vobel[nr].npages;
		long *current_point=vobel[nr].page_offsets;
		while(remaining_longs--)
			lsb2msb(current_point++);
	}
#endif
    ls=vobel[nr].page_offsets[0]-sizeof(long)*(vobel[nr].npages+3);
    if(!(vobel[nr].pairbuffer=malloc(ls))) goto zle;
    if (!fread(vobel[nr].pairbuffer,1,ls,vobel[nr].f)) goto zle;
    /* tak jakby wszystko wczytane... */
    if (!(vobel[nr].pairs=malloc(sizeof(char *)*2*vobel[nr].npages))) goto zle;
    for (i=0,c=vobel[nr].pairbuffer;i<2*vobel[nr].npages;i++) {
	vobel[nr].pairs[i]=c;
	while(*c++);
    }
    vobel[nr].actual_page=-1;
    vobel[nr].lastpage=0;
    vobel[nr].lastindex=-1;
    return;
zle:
    alt_fprintf(asciionly_mode,stderr,"Błąd odczytu słownika %s\n",avname);
    exit(21);
}

read_page(nr,np) int nr,np;
{
    if (vobel[nr].actual_page==np) return;
    fseek(vobel[nr].f,vobel[nr].page_offsets[np],SEEK_SET);
    if (!fread(&vobel[nr].wordspp,sizeof(short),1,vobel[nr].f)) goto zle;
    if (!fread(&vobel[nr].dsize,sizeof(short),1,vobel[nr].f)) goto zle;
    if (!fread(&vobel[nr].dvoffset,sizeof(short),1,vobel[nr].f)) goto zle;
#ifdef MSB_FIRST_PROCESSOR
		short_lsb2msb(&vobel[nr].wordspp);
		short_lsb2msb(&vobel[nr].dsize);
		short_lsb2msb(&vobel[nr].dvoffset);
#endif
    if (!fread(vobel[nr].body,1,(long)vobel[nr].dsize,vobel[nr].f)) goto zle;
#ifdef MSB_FIRST_PROCESSOR
	{
		int remaining_shorts=vobel[nr].wordspp;
		short *current_point=(short *)vobel[nr].body;
		while(remaining_shorts--)
			short_lsb2msb(current_point++);
	}
#endif
    vobel[nr].actual_page=np;
    vobel[nr].sizes=(short *)vobel[nr].body;
    vobel[nr].first=vobel[nr].body+sizeof(short)*vobel[nr].wordspp;
    return;
zle:
    alt_fprintf(asciionly_mode,stderr,"Błąd odczytu\n");
    exit(100);
}

char buf1[8192],buf2[8192];
struct markpol
    {char *pm;int flag;int mask;} markpol[]={
{"przymiotnik",1,15},
{"przysłówek",2,15},
{"spójnik",3,15},
{"liczebnik",4,15},
{"partykuła",5,15},
{"przedrostek",6,15},
{"przyimek",7,15},
{"zaimek",8,15},
{"rzeczownik",9,15},
{"czasownik posiłkowy",10,15},
{"czasownik nieprzechodni",11,15},
{"czasownik nieosobowy",12,15},
{"czasownik zwrotny",13,15},
{"czasownik przechodni",14,15},	/* 16 - 4 bajty */
{"czasownik",15,15},


{"rodzaj żeński",16,0x30},		/* 4 bajty */
{"rodzaj męski",32,0x30},
{"rodzaj nijaki",16+32,0x30},

{"liczba pojedyncza",64,0xc0},
{"liczba mnoga",128,0xc0},
{"tylko liczba mnoga",128+64,0xc0},

{"czas przeszły",2048,2048|4096|8192|16384},
{"czas teraźniejszy",4096,2048|4096|8192|16384},
{"czas przyszły",2048+4096,2048|4096|8192|16384},
{"bezokolicznik",8192,2048|4096|8192|16384},



{"stopień najwyższy",16384,2048|4096|8192|16384},
{"regularny",256,256},	/* 3 bajty */
{"wyraz potoczny",1024,1024},
{"skrót",512,512},
{"stopień wyższy",16384|8192,2048|4096|8192|16384},
{0,0}};

/* ciągi unikowe */
char haslo[2][32]={"\x1b[1;33m","\x1b[0m"};
char grama[2][32]={"\x1b[32m","\x1b[0m"};
char vide[2][32]={"\x1b[33m","\x1b[0m"};
char count[2][32]={"\x1b[33m","\x1b[0m"};
char header[2][32]={"\x1b[31m","\x1b[0m"};

parsestr(c) char *c;
{
    char *d;int i,v;
    for (d=c;*c;) if (*c!='\\') *d++=*c++;
    else {
	c++;v=0;
	for (i=0;i<3;i++) if (*c>='0' && *c<'8') v=(v<<3) | ((*c++)-'0'); else break;
	*d++=v;
    }
    *d=0;
}
linetoparam(line) char *line;
{
    char cv1[32],cv2[32],*c,*d;int cx,i;
    if (!strchr("hgpwc",*line)) return;
    cx=*line++;
    while(*line && isspace(*line)) line++;
    if (*line++!='\"') return;

    for (i=0;*line && *line!='\"';i++,line++) if (i<31) cv1[i]=*line;
    cv1[i]=0;
    parsestr(cv1);
    if (!*line) return;
    line++;
    while (*line) if (*line++=='\"') break;
    if (!line) return;
    for (i=0;*line && *line!='\"';i++,line++) if (i<31) cv2[i]=*line;
    cv2[i]=0;
    parsestr(cv2);
    if (!*line) return;
    switch(tolower(cx)) {
	case 'h': strcpy(haslo[0],cv1);strcpy(haslo[1],cv2);break;
	case 'g': strcpy(grama[0],cv1);strcpy(grama[1],cv2);break;
	case 'p': strcpy(vide[0],cv1);strcpy(vide[1],cv2);break;
	case 'w': strcpy(count[0],cv1);strcpy(count[1],cv2);break;
	case 'c': strcpy(header[0],cv1);strcpy(header[1],cv2);break;
    }
}

getsaprc()
{
    char terminal[256],*c,*d;int got;
    char fline[256];
    FILE *f;
    if (c=getenv("HOME")) {
	strcpy(fline,c);
	strcat(fline,DIRECTORY_SEPARATOR);
	strcat(fline,LOCAL_SAPRC_FILENAME);
	if (f=fopen(fline,"rb")) goto sapok;
    }
    if (!(f=fopen(GLOBAL_SAPRC_FULLPATH,"rb"))) return;
sapok:
    if (!(c=getenv("TERM"))) strcpy(terminal,"dummy");else strcpy(terminal,c);
    // printf("Current terminal:%s\n",terminal);
    for (c=terminal;*c;c++) *c=tolower(*c);
    got=0;
    for (;;) {
	if (!got) {
	    if (!fgets(fline,256,f)) break;
	}
	c=fline;got=0;
	while(*c && isspace(*c)) c++;
	if (*c=='#') continue;
	if (!*c) continue;
	if (!strncmp(c,"term",4)) {
	    c+=4;
	    while (*c && *c!='=') c++;
	    if (!*c) continue;
	    c++;
	    d=c;
	    while(*d && !isspace(*d)) d++;
            *d=0;
	    for (d=c;*d;d++) *d=tolower(*d);
	    //printf("Terminal desc:%s\n",c);
//	    if (strcmp(c,terminal)) continue;
	    if (!strcmp(c,terminal)) break;
	    for (;;) {
		if (!fgets(fline,256,f)) break;
		c=fline;
		while(*c && isspace(*c)) c++;
		if (!*c || *c=='#') continue;
		if (*c!='.') {
		    got=1;
		    break;
		}
		linetoparam(c+1);
	    }
	    continue;
	}
    }
}





mksecbuf(hass) char *hass;
{
    char *c,*d;int v,i,mc,cdoll;
    c=buf1;
    d=buf2;
    cdoll=0;
    strcpy(d,haslo[0]);strcat(d,hass);strcat(d,haslo[1]);strcat(d," - ");d+=strlen(d);
    while (*c) {
        switch(*c) {
	case ',':
	case '.':
	case ')':
	*d++=*c++;
	if (!strchr(".,",*c)) *d++=' ';
	continue;
	case '$':
	    if (cdoll) {*d++=';';*d++=' ';}
	    d+=sprintf(d,"%s%c)%s ",count[0],'a'+cdoll,count[1]);
	    cdoll++;c++;
	    continue;
	case '-':
	    strcpy(d," - ");d+=3;c++;continue;

        case '{':
	    strcpy(d,haslo[0]);d+=strlen(d);c++;continue;

	case '}':
	    cdoll=0;
	    strcpy(d,haslo[1]);strcat(d," - ");d+=strlen(d);c++;continue;

	case '*':
	    strcpy(d,hass);
	    d+=strlen(d);c++;
	    continue;

	case '=':
	    strcpy(d,vide[0]);
	    strcat(d,"patrz:");
	    strcat(d,vide[1]);
	    strcat(d," ");
	    d+=strlen(d);c++;continue;

	case '#':

	    strcpy(d,grama[0]);d+=strlen(d);
	    c++;
	    v=((*c++)<<8) & 0xff00;
	    v|=(*c++)&255;
	    for (i=mc=0;markpol[i].pm;i++) if ((v& markpol[i].mask)==markpol[i].flag) {
		if (mc) *d++=',';
		strcpy(d,markpol[i].pm);
		d+=strlen(d);
		*d++=' ';
		mc=1;
		}
	    strcpy(d,grama[1]);
	    d+=strlen(d);
	    continue;
	    }
	*d++=*c++;

	}
    *d=0;
}


findslowo(slowo,nr,f) char *slowo;int nr;FILE *f;
{

    int i,j,n,off,ixi;char *c;
    if (slowo[0]=='<') {
	if (vobel[nr].lastindex<=0) {
	    if (vobel[nr].lastpage<=0) {
outofvob:	sprintf(buf2,"poza zakresem słownika\n");
		return;
	    }
	    read_page(nr,--vobel[nr].lastpage);
	    vobel[nr].lastindex=vobel[nr].wordspp-1;
	}
	else {
	    read_page(nr,vobel[nr].lastpage);
	    vobel[nr].lastindex--;
	}
fslowo:
	off=vobel[nr].dvoffset;
	c=vobel[nr].first;
	for (i=0;i<vobel[nr].lastindex;i++) {
	    while(*c++);
	    off+=vobel[nr].sizes[i];
	}
	slowo=c;
	goto fxslowo;
    }
    if (slowo[0]=='>') {
	read_page(nr,vobel[nr].lastpage);
	if (vobel[nr].lastindex>=vobel[nr].wordspp-1) {
	    if (vobel[nr].lastpage>=vobel[nr].npages-1) goto outofvob;
	    read_page(nr,++vobel[nr].lastpage);
	    vobel[nr].lastindex=0;
	}
	else vobel[nr].lastindex++;
	goto fslowo;
    }
    if (c=strchr(slowo,'*')) {
	if (c[1]) goto xmatch;
	for (i=0;i<vobel[nr].npages;i++) {
	    n=l_match(vobel[nr].pairs[2*i],slowo);
	    if (n>0) goto noslowo;
	    n=l_match(vobel[nr].pairs[2*i+1],slowo);
	    if (n>=0) goto okfpage;
	}
	goto noslowo;
okfpage:
	read_page(nr,i);
	c=vobel[nr].first;
	for (i=0,off=vobel[nr].dvoffset;i<vobel[nr].wordspp;i++) {
	    n=l_match(c,slowo);
	    if (!n) {
		slowo=c;
		goto rslowo;
	    }
	    if (n>0) break;
	    while(*c++);
	    off+=vobel[nr].sizes[i];
	}
	goto noslowo;
    }
    for (i=0;i<vobel[nr].npages;i++) {
	n=l_compare(vobel[nr].pairs[2*i],slowo);
	if (n>0) goto noslowo;
	n=l_compare(vobel[nr].pairs[2*i+1],slowo);
	if (n>=0) goto okpage;
    }
noslowo:
    sprintf(buf2,"Nie znalazłem słowa %s%s%s\n",haslo[0],slowo,haslo[1]);
    return;
okpage:
    read_page(nr,i);
    c=vobel[nr].first;
    for (i=0,off=vobel[nr].dvoffset;i<vobel[nr].wordspp;i++) {
	n=l_compare(c,slowo);
	if (!n) goto rslowo;
	if (n>0) break;
	while(*c++);
	off+=vobel[nr].sizes[i];
    }
    goto noslowo;
rslowo:
    vobel[nr].lastpage=vobel[nr].actual_page;
    vobel[nr].lastindex=i;
fxslowo:
    memcpy(buf1,vobel[nr].body+off,vobel[nr].sizes[i]);
    buf1[vobel[nr].sizes[i]]=0;
    mksecbuf(slowo);
    return;
xmatch:
    ixi=0;
    for (i=0;i<vobel[nr].npages;i++) {
        n=l_match(vobel[nr].pairs[2*i],slowo);
	if (n>0) {
	    if (!ixi) goto noslowo;
	    return;
	}
	n=l_match(vobel[nr].pairs[2*i+1],slowo);
	if (n<0) continue;
	read_page(nr,i);
	for (c=vobel[nr].first,off=vobel[nr].dvoffset,j=0;j<vobel[nr].wordspp;j++) {
	    n=l_match(c,slowo);
	    if (n>0) {
		if (!ixi) goto noslowo;
		return;
	    }
	    if (!n && !l_pmatch(c,slowo)) {
		if (ixi)alt_fprintf(asciionly_mode,f,"%s--\n",buf2);
		ixi++;
		vobel[nr].lastpage=vobel[nr].actual_page;
		vobel[nr].lastindex=j;
		memcpy(buf1,vobel[nr].body+off,vobel[nr].sizes[j]);
		buf1[vobel[nr].sizes[j]]=0;
		mksecbuf(c);
		if (ixi>=100) return; /* no, to nie miejsce na drukowanie słownika! */
	    }
	    while(*c++);
	    off+=vobel[nr].sizes[j];
	}
    }
    if (!ixi) goto noslowo;
}
char slowo[32];
trim(char *c)
{
    char *d;int n;
    for(d=c;*c;) if (n=l_tolower(*c++)) *d++=n;
    *d=0;
}

char tmpoutname[256];
char *helpstring=""
"Jeśli słowa pobierane są z pliku lub standartowego wejścia, w każdej\n"
"linii może być tylko jedno słowo lub polecenie. Oprócz pełnych słów\ndopuszczalne są:\n"
"	-p (przełączenie w tryb polsko-angielski)\n"
"	-a (przełączenie w tryb angielsko-polski)\n"
"	<  (poprzednie słowo)\n"
" 	>  (następne słowo)\n"
"	tekst* powoduje odnalezienie pierwszego słowa\n		rozpoczynającego się od \"tekst\"\n"
"	.  (koniec przetwarzania)\n"
"Program akceptuje również coś w rodzaju wyrażeń - jeśli gwiazdka\n"
"nie jest ostatnim znakiem wprowadzanego słowa, będą wypisane wszystkie\n"
"słowa pasujące do wzorca w którym gwiazdka zastępuje dowolny (również pusty)\n"
"ciąg znaków. Ilość wypisanych haseł jest ograniczona do 100.\n"
"";
main(int argc,char *argv[])
{
    int opcja,voc,lmode,vsl;
    char *tmp,*infname;
    char systin[256];
    FILE *f,*fi;

    mk_convt();
    lmode=0;
    asciionly_mode=0;

    while((opcja=alt_getopt(argc,argv,"ivhpalf:"))!=EOF) {
        switch(opcja) {
	    case 'v': alt_fprintf(asciionly_mode,stderr,"%s",verstring);exit(0);
	    case 'h': lmode|=2;break;
	    // case 'x': lmode|=4;break;
	    case 'l': lmode|=1;break;
	    case 'p': lmode|=8;break;
	    case 'a': lmode|=16;break;
	    case 'f': infname=alt_optarg;lmode|=32;break;
		 case 'i': asciionly_mode=1;break;
            }
    }
    if (lmode & 2) { //help
	alt_fprintf(asciionly_mode,stderr,"%s\n",verstring);
	alt_fprintf(asciionly_mode,stderr,"Copyright (c)1998 Bohdan R. Rau\n");
	alt_fprintf(asciionly_mode,stderr,"Copyright (c)2001 Daniel Mealha Cabrita\n");
        alt_fprintf(asciionly_mode,stderr,"Sposób użycia:\n",argv[0]);
	alt_fprintf(asciionly_mode,stderr," %s -v    wyświetla wersję programu\n",argv[0]);
	alt_fprintf(asciionly_mode,stderr," %s -h    pomoc (to, co czytasz)\n",argv[0]);
	alt_fprintf(asciionly_mode,stderr," %s [-apli] [słowo] ...\n",argv[0]);
	alt_fprintf(asciionly_mode,stderr," %s [-apli] -f <file>\n",argv[0]);
	alt_fprintf(asciionly_mode,stderr,"Opcje:\n");
	alt_fprintf(asciionly_mode,stderr," -f <file> - pobieranie słów z pliku\n");
	alt_fprintf(asciionly_mode,stderr," -l        - filtrowanie wyjścia przez less -r\n");
        alt_fprintf(asciionly_mode,stderr," -i        - tekst tylko na ASCII\n");
        alt_fprintf(asciionly_mode,stderr," -a        - słownik angielsko-polski\n");
	alt_fprintf(asciionly_mode,stderr," -p        - słownik polsko-angielski (domyślnie)\n");
	alt_fprintf(asciionly_mode,stderr,"%s",helpstring);
	exit(0);
	}
    if (lmode & 4) {
        alt_fprintf(asciionly_mode,stderr,"Jeszcze nie działa :-(\n");
	exit(0);
	}
    voc='p';
    if (lmode & 16) voc='a';

    if (!(lmode & 32)) { // dane z linii czy stdin
        if (argc>alt_optind) lmode|=64; // dane z linii;
    }

        // sprawdzenie dla less

    if (lmode & 1) {
	if (lmode & (32 | 64)) lmode|=128; /* less wywoływany na końcu
					      gdy dane z linii lub pliku
					   */
    }
    if (lmode & 32) {
	if (strcmp(infname,"-")) fi=fopen(infname,"rb"); else fi=stdin;
	if (!fi) exit(100);
    } else if (!(lmode & 64)) fi=stdin;
    else fi=0;
    getsaprc();
    // jeśli less ma być otwarty na początku:
    if (lmode & 128) {
        tmp=tmpnam(tmpoutname);
	if (!tmp) exit(100);
	if (!(f=fopen(tmp,"w"))) exit(100);
	}
    else f=stdout;
    ReadVobel(FILENAME_DATABASE_1,0);
    ReadVobel(FILENAME_DATABASE_2,1);

    for (;;) {
        if (fi) {
            if (!fgets(slowo,32,fi)) break;
	    }
	else {
            if (alt_optind>=argc) break;
	    memcpy(slowo,argv[alt_optind++],31);
	    slowo[31]=0;
	    }
	if (slowo[0]=='.') break;
        if (slowo[0]=='-') {
            if (tolower(slowo[1])=='p') voc='p';else
	    if (tolower(slowo[1])=='a') voc='a';
	    continue;
	    }
	trim(slowo);
			if (asciionly_mode){
		  		transform_from_ascii(asciionly_mode,slowo);
#ifdef OS_AMIGAOS
			} else {
				transform_fromto_amigapl_iso(slowo);
#endif
			}
        if (!slowo[0]) continue;
        if ((lmode & 1) && !(lmode & 128)) { // less wywoływany za każdym razem
            tmp=tmpnam(tmpoutname);
            if (!(f=fopen(tmp,"w"))) exit(100);
	    }
	alt_fprintf(asciionly_mode,f,"%s%s%s\n",header[0],
            (voc=='p') ? "Słownik polsko-angielski":"Słownik angielsko-polski",header[1]);
	findslowo(slowo,(voc=='p')?1:0,f);
        alt_fprintf(asciionly_mode,f,"%s",buf2);
        if ((lmode & 1) && !(lmode & 128)) { // less wywoływany za każdym razem
            fclose(f);
            sprintf(systin,"less -r %s\nrm -f %s",tmp,tmp);
            system(systin);
	    }
	}
    if (lmode & 128) { // less wywoływany na końcu
        fclose(f);
        sprintf(systin,"less -r %s\nrm -f %s",tmp,tmp);
        system(systin);
    }
    exit(0);
}
