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

char* getline(FILE* f) {
  char* str=(char*)malloc(sizeof(char));
  int c,i=0;
  if ((c=fgetc(f))==-1) return NULL;
  while((c!=-1)&&(c!='\n'))
  {
i++;
str=(char*)realloc(str, sizeof(char)*(i+1));
str[i-1]=c;
c=fgetc(f);
  }
  i++;
  str=(char*)realloc(str, sizeof(char)*(i+1));
  str[i-1]='\n';
  str[i]='\0';
  return str;  }


//------------------------------------- sort_two_to_one --------------------------
FILE *F, *F1, *F2;
int flag=1;

int sort_two_to_one() {
  char *str1, *str2;
  int tmpf=1;
  int tmpp=0;
   F=(fopen("temp.c", "r"));
   F1=(fopen("temp1.c", "w"));
   F2=(fopen("temp2.c", "w"));
  str1=getline(F);
  if (!str1) return 1;
  while(str2=getline(F))
  {
if (tmpf) fputs (str1, F1); else fputs (str1, F2);
if (strcmp(str1, str2)*flag>0) 
{ tmpp=1;  tmpf=0; }
free(str1);
str1=str2;
  }
  if (tmpf) fputs (str1, F1); else fputs (str1, F2);
  free(str1);
  fclose(F);
  fclose(F1);
  fclose(F2);
  return tmpp;   }


//------------------------------------- conflux ----------------------------------

int conflux() {
  char* str1, *str2, *str;
  int tmpftr1, tmpftr2;
  str1=getline(F1);
  str2=getline(F2);
  if ((!str1) && (!str2)) return 0;
  if (!str1)
  {
fputs (str2, F);
free(str2);
while(str2=getline(F2))
{
  fputs (str2, F);
  free(str2);
} return 0;
  }
  if (!str2)
  {
fputs (str1, F);
free(str1);
while(str1=getline(F1))
{
  fputs (str1, F);
  free(str1);
} return 0;
  }
  while(1)
  {
if (strcmp(str1, str2)*flag<=0)
{
  fputs (str1, F);
  tmpftr1=ftell(F1);
  str=getline(F1);
  if (!str || strcmp(str, str1)*flag<=0)
  {
if (str) fseek(F1, tmpftr1, SEEK_SET);
free(str1);
str1=str;
fputs (str2, F);
tmpftr2=ftell(F2);
str=getline(F2);
while(str && strcmp(str, str2)*flag>0)
{
  free(str2);
  str2=str;
  fputs (str2, F);
  tmpftr2=ftell(F2);
}
if (str) fseek(F2, tmpftr2, SEEK_SET);
free(str);
return 1;
  }
  free(str1);
  str1=str;
}
else
{
  fputs (str2, F);
  tmpftr2=ftell(F2);
  str=getline(F2);
  if (!str || strcmp(str, str2)*flag<=0)
  {
if (str) fseek(F2, tmpftr2, SEEK_SET);
free(str2);
str2=str;
fputs (str1, F);
tmpftr1=ftell(F1);
str=getline(F1);
while(str && strcmp(str, str1)*flag>0)
{
  free(str1);
  str1=str;
  fputs (str1, F);
  tmpftr1=ftell(F1);
}
if (str) fseek(F1, tmpftr1, SEEK_SET);
free(str);
return 1;
  }
  free(str2);
  str2=str;
}
  }}

//--------------------------------------------------------------------------------
//------------------------------------- main -------------------------------------

int main(int argc, char** argv)
{
  char *str1, *str2, *str;
  int i=0;

  if (argc<2) return 1;
// ------------------------------------- sort direction --------------------------
  F=fopen("temp.c", "w");
  i=1;
  if (strcmp(argv[1],"-d")==0) {
   if (strcmp(argv[2],"up")==0) flag=1;
   else if (strcmp(argv[2],"down")==0) flag=-1;
else return 1;
i=3;   }
//------------------------------------- files linking ----------------------------
  for(; i<argc; i++)
  {
F1=fopen(argv[i], "r");
while (str = getline (F1))
{
  fputs (str,F);
  free (str);
}
fclose(F1);
  }
  fclose(F);
//------------------------------------- main loop --------------------------------
  while(sort_two_to_one())
   {
F1=(fopen("temp1.c", "r"));
F2=(fopen("temp2.c", "r"));
F=(fopen("temp.c", "w"));
while(conflux());
fclose(F1);
fclose(F2);
fclose(F);
   }
  free(str);
//------------------------------------- output -----------------------------------
  F=fopen("temp.c", "r");
  while(str=getline(F)) printf ("%s", str);
  fclose(F);
  return 0;
}
