#if 0

 gcc -s -c convpl.c $0
 gcc -s -o convpl convpl.o
 rm convpl.o

 exit

#endif

/*
 ######################################################################
 ##                                                                  ##
 ## ConvertPL - program do konwersji pomiedzy roznymi standardami    ##
 ## polskich znakow oraz roznymi standardami konca linii.            ##
 ##                                                                  ##
 ## Aby skompilowac ten program pod systemem UNIX napisz:            ##
 ## sh convpl.c                                                      ##
 ##                                                                  ##
 ## Aby skompilowac go na Amidze z uzyciem kompilatora GNU C napisz: ##
 ## make                                                             ##
 ##                                                                  ##
 ## Przy kompilowaniu na pececie pod Borland C trzeba wpisac PC w    ##
 ## polu "Defines" w Options->Compiler->Code generation...           ##
 ##                                                                  ##
 ##---------------------------------------------------------------   ##
 ##                                                                  ##
 ## Moj adres:                                                       ##
 ##                                                                  ##
 ## Piotr Pawlow                                                     ##
 ## ul. Lewartowskiego 12/46                                         ##
 ## 00-185 Warszawa                                                  ##
 ##                                                                  ##
 ## Email: pp@cs.com.pl                                              ##
 ## Homepage: http://www.cs.com.pl/amiga/index.html                  ##
 ##                                                                  ##
 ######################################################################
*/

#include <stdio.h>
#include <string.h>


#ifdef PC
  #define MACHINE "pc"
  #include <dir.h>
  #define STRCCMP stricmp
#else
  #define STRCCMP strcasecmp
  #include <unistd.h>
  #include <machine/param.h>
#endif


char porownanie[20]="                  ";
char wymiana[20]="                  ";
char xxx=0;
const char *zlearg="Zle argumenty (napisz -h aby uzyskac pomoc).\n";

void exit(int);

int hex(char z1,char z2)
{
  if ((((z1>='0')&&(z1<='9'))||((z1>='A')&&(z1<='F'))||((z1>='a')&&(z1<='f')))&&(((z2>='0')&&(z2<='9'))||((z2>='A')&&(z2<='F'))||((z2>='a')&&(z2<='f'))))
  {
    if (z1>='a') z1=z1-'a'+10;
    else if (z1>='A') z1=z1-'A'+10;
    else if (z1>='0') z1=z1-'0';
    if (z2>='a') z2=z2-'a'+10;
    else if (z2>='A') z2=z2-'A'+10;
    else if (z2>='0') z2=z2-'0';
    return(z1*16+z2);
  }
  else return(-1);
}

int get_char(FILE *plik,char mime)
{

char z1,z2,znak;
int wynik;

  if (mime==0) return(fgetc(plik));
  else
  {
    znak=fgetc(plik);
    if (znak=='=')
    {
      z1=fgetc(plik);
      if (z1==10) return(get_char(plik,mime));
      z2=fgetc(plik);
      if ((wynik=hex(z1,z2))==-1)
      {
        fseek(plik,-2,SEEK_CUR);
        return(znak);
      }
      else return(wynik);
    }
    return(znak);
  }
}

void copy(char *zrodlo)
{
  if (xxx==0)
  {
    strcpy(porownanie,zrodlo);
    xxx++;
  }
  else if (xxx==1)
  {
    strcpy(wymiana,zrodlo);
    xxx++;
  }
  else
  {
    printf(zlearg);
    exit(0);
  }
}

int main(int argc,char *argv[])

{
FILE *plik;
FILE *plik2;

char amigapl_zn[20]="";
char bezogonkow_zn[20]="acelnoszzACELNOSZZ";
char isolatin_zn[20]="󶿼ʣӦ";
char latin2_zn[20]="䢘";
char mac_zn[20]="ė";
char mzv_zn[20]="";
char fidomzv_zn[20]="";
char win_zn[20]="󜿟ʣӌ";
char xjp_zn[20]="";

long i,j;
char znak=0,pznak=0,koniec,conv=0,mimeflag=0;
char pz=0,pd=0;
char *temporary=NULL;
const char min=3,max=7;

  if (argc==1)
  {
    printf("convpl (-h)|(plik_zrodlowy [-amigapl|-bez|-fidomzv|-isolatin|-latin2|-mac|-mzv|-win|-xjp] [-MIME] [plik_wynikowy] [-amigapl|-bez|-fidomzv|-isolatin|-latin2|-mac|-mzv|-win|-xjp] [-LF|-CR|-CRLF])\n");
    return(0);
  }
  if (argc==2) if (STRCCMP(argv[1],"-h")==0)
  {
    printf("\nConvertPL 1.0 - program do konwersji pomiedzy standardami polskich liter.\n\n");
    printf("Wywolanie: convpl plik_zrodlowy [-standard] [-MIME] [plik_wynikowy] [-standard] [-konieclinii]\n\n");
    printf("Dostepne standardy:\n");
    printf("-amigapl  - format AmigaPL stosowany na Amidze\n");
    printf("-bez      - bez polskich znakow\n");
    printf("-fidomzv  - FIDO Mazovia\n");
    printf("-isolatin - ISO Latin 2\n");
    printf("-latin2   - normalny Latin 2\n");
    printf("-mac      - standard Macintosha\n");
    printf("-mzv      - standard Mazovii\n");
    printf("-win      - standard uzywany w systemie Windows\n");
    printf("-xjp      - stary format Amigowy ks. Pikuli\n\n");
    printf("-MIME     - uproszczone dekodowanie MIME.\n");
    printf("            Kazdy ciag =XX zostaje zamieniony na znak o kodzie XX.\n\n");
    printf("Konwersja konca linii:\n");
    printf("-LF       - linia bedzie sie konczyc kodem 10 - Line Feed (UNIX,Amiga)\n");
    printf("-CR       - linia bedzie sie konczyc kodem 13 - Carriage Return (Macintosh)\n");
    printf("-CRLF     - linia bedzie zakonczona oboma kodami (PC)\n\n");
    return(0);
  }
  if (argc<min)
  {
    printf("Za malo argumentow (napisz -h aby uzyskac pomoc).\n");
    return(0);
  }
  if (argc>max)
  {
    printf("Za duzo argumentow (napisz -h aby uzyskac pomoc).\n");
    return(0);
  }
  for (i=1; i<argc; i++)
  {

    if (*argv[i]!='-')
    {
      if (pz==0) pz=i;
      else if (pd==0) pd=i;
      else
      {
        printf(zlearg);
        return(0);
      }
    }
    else
    {
      if (STRCCMP(argv[i],"-MIME")==0)
      {
        if (mimeflag==0) mimeflag=1;
        else
        {
          printf(zlearg);
          return(0);
        }
      }
      else if (STRCCMP(argv[i],"-LF")==0) conv=1;
      else if (STRCCMP(argv[i],"-CR")==0) conv=2;
      else if (STRCCMP(argv[i],"-CRLF")==0) conv=3;
      else if (STRCCMP(argv[i],"-amigapl")==0) copy(amigapl_zn);
      else if (STRCCMP(argv[i],"-isolatin")==0) copy(isolatin_zn);
      else if (STRCCMP(argv[i],"-mzv")==0) copy(mzv_zn);
      else if (STRCCMP(argv[i],"-fidomzv")==0) copy(fidomzv_zn);
      else if (STRCCMP(argv[i],"-mac")==0) copy(mac_zn);
      else if (STRCCMP(argv[i],"-win")==0) copy(win_zn);
      else if (STRCCMP(argv[i],"-xjp")==0) copy(xjp_zn);
      else if (STRCCMP(argv[i],"-latin2")==0) copy(latin2_zn);
      else if (STRCCMP(argv[i],"-bez")==0) copy(bezogonkow_zn);
      else
      {
        printf(zlearg);
        return(0);
      }
    }
  }
  if (xxx==1)
  {
    printf(zlearg);
    return(0);
  }
  if (pd==0) pd=pz;
  plik=fopen(argv[pz],"r");
  if (ferror(plik)!=0)
  {
    printf("Blad odczytu.\n");
    return(0);
  }
  if (strcmp(MACHINE,"amiga")==0)
    i=STRCCMP(argv[pz],argv[pd]);
  else i=strcmp(argv[pz],argv[pd]);
  if (i==0)
  {
    #ifdef PC
      temporary=mktemp("convXXXXXX");
    #else
      temporary=mktemp("/tmp/cplXXX");
    #endif
    if (temporary==NULL)
    {
      printf("Nie moge stworzyc pliku roboczego.\n");
      return(0);
    }
    plik2=fopen(temporary,"w");
  }
  else plik2=fopen(argv[pd],"w");
  if (ferror(plik2)!=0)
  {
    printf("Blad zapisu.\n");
    return(0);
  }
  while (feof(plik)==0)
  {
    pznak=znak;
    znak=get_char(plik,mimeflag);
    if (feof(plik)==0)
    {
      koniec=0;
      if ((znak==10)||(znak==13))
      {
        if (conv==0) fputc(znak,plik2);
        else
        {
          if (((znak==10)&&(pznak!=13))||(znak==13))
          {
            if (conv==1) fputc(10,plik2);
            if (conv==2) fputc(13,plik2);
            if (conv==3)
            {
              fputc(13,plik2);
              fputc(10,plik2);
            }
          }
        }
      }
      else
      {
        if (xxx==2)
        for (j=0; (j<18)&&(koniec==0); j++)
        {
          if (znak==porownanie[j])
          {
            znak=wymiana[j];
            koniec=1;
          }
        }
        fputc(znak,plik2);
      }
    }
  }
  fclose(plik);
  fclose(plik2);
  if (temporary!=NULL)
  {
    plik=fopen(temporary,"r");
    plik2=fopen(argv[pd],"w");
    if (ferror(plik2)!=0)
    {
      printf("Blad zapisu.\n");
      return(0);
    }
    while (feof(plik)==0)
    {
      znak=fgetc(plik);
      if (feof(plik)==0) fputc(znak,plik2);
    }
    fclose(plik);
    fclose(plik2);
    if (remove(temporary)!=0)
    {
      printf("Nie moge usunac pliku roboczego.\n");
      return(0);
    }
  }
  return(0);
}

