EDITOR.c



/* IMPLEMENTACION DE UN EDITOR DE LINEA
	BASADA EN LISTAS DOBLENTE LIGADAS

   J. Rafael R. Ochoa                    
---------------------------------------------------------------------------*/
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

struct Ed_Line{
   char text_line[80];
   int num;
   struct Ed_Line *sig;
   struct Ed_Line *ant;
};

struct Ed_Line *pent_list;
struct Ed_Line *uent_list;

struct Ed_Line *Busca_Line(int num_line);
struct Ed_Line *almacena_deo(struct Ed_Line *i);

int Menu(), Introducir(int num_line);
void Ajustar(int num, int incr), Borrar_Line(void);
void Listar_Edline(void), Guardar_Arch(char *Nom_Arch), Cargar_Arch(char *Nom_Arch);
void Imprime_Arch(void);

main(int argc, char *argv[])
{
  char num_tmp[15], name_arch[15];
  int opc, num_line = 1;
  struct Ed_line *tmp;

/* inicializacion de la lista */

  pent_list=NULL;
  uent_list=NULL;

  clrscr();

/* Leer los archivos desde el prompt del sistema */

  if(argc==2){
    Cargar_Arch(argv[1]);
  }

  for(;;){
     clrscr();
     opc = Menu();
     switch(opc){
       case 1:
	  printf("Numero de la linea a introducir -> ");
	  gets(num_tmp);
	  num_line = atoi(num_tmp);
	  Introducir(num_line);
	  break;
       case 2:
	  Listar_Edline();
	  getch();
	  break;
       case 3:
	  Borrar_Line();
	  break;
       case 4:
	  printf("Dame el numero de Linea a Buscar -> ");
	  gets(num_tmp);
	  num_line = atoi(num_tmp);
//	  tmp=Busca_Line(num_line);
//	  printf("%d : %s\n", tmp->num, tmp->text_line);
	  getch();
	  break;
       case 5:
	  printf("Dame el nombre del archivo: ");
	  gets(name_arch);
	  Cargar_Arch(name_arch);
	  break;
       case 6:
	  printf("Dame el nombre del archivo a Guardar: ");
	  gets(name_arch);
	  Guardar_Arch(name_arch);
	  break;
       case 7:
	  Imprime_Arch();
	  getch();
       case 8:
	  exit(1);
     }
  }
}

int Menu()
{
  char num_tmp[15];
  int num_sel;

  gotoxy(6,3);
  puts("1.- Introducir una Linea");
  gotoxy(6,5);
  puts("2.- Mostrar la Lista");
  gotoxy(6,7);
  puts("3.- Eliminar una Linea");
  gotoxy(6,9);
  puts("4.- Buscar una Linea");
  gotoxy(46,3);
  puts("5.- Abrir Archivo");
  gotoxy(46,5);
  puts("6.- Salvar Archivo");
  gotoxy(46,7);
  puts("7.- Imprimir la Lista");
  gotoxy(46,9);
  puts("8.- Salir a Sistema");
  do{
    printf("\nOpcion -> ");
    gets(num_tmp);
    num_sel = atoi(num_tmp);
  }while(num_sel<0 || num_sel>8);

  return num_sel;
}

int Introducir(int num_line)
{
  struct Ed_Line *info;

  for(;;){
     info = malloc(sizeof(struct Ed_Line));
     if(!info){
       printf("Fallo de peticion de Memoria\n");
       exit(1);
     }

     printf("%d: ", num_line);
     gets(info->text_line);
     info->num = num_line;
     if(*info->text_line){
	if(Busca_Line(num_line)) Ajustar(num_line, 1);

	if(*info->text_line) pent_list = almacena_deo(info);
     }
     else break;
     num_line++;
  }
  return num_line;
}

struct Ed_Line *Busca_Line(int num_line)
{
  struct Ed_Line *info;

  info = pent_list;
  while(info){
    if(num_line == info->num){
       return info;
    }
    info = info -> sig;
  }
  return NULL;
}


void Ajustar(int num, int incr)
{
  struct Ed_Line *i;

  i = Busca_Line(num);

  while(i){
     i->num = i->num+incr;
     i = i->sig;
  }
}

struct Ed_Line *almacena_deo(struct Ed_Line *i)
{
  struct Ed_Line *pold, *p;

  if(!uent_list){
     i->sig = NULL;
     i->ant = NULL;
     uent_list = i;

     return i;
  }

  p = pent_list;

  pold = NULL;
  while(p){
    if(p->num < i->num){
       pold = p;
       p = p->sig;
    }
    else{
      if(p->ant){
	 p->ant->sig = i;
	 i->sig = p;
	 p->ant = i;
	 return pent_list;
       }
       i->sig = p;
       i->ant = NULL;
       p->ant = i;
       return i;
    }
  }
  pold->sig=i;
  i->sig=NULL;
  i->ant = pold;
  uent_list = i;
  return(pent_list);
}

void Listar_Edline(void)
{
  struct Ed_Line *info;

  info = pent_list;

  while(info){
     printf("%d : %s\n", info->num, info->text_line);
     info = info->sig;
  }
  printf("\n");
}

void Borrar_Line(void)
{
  struct Ed_Line *info;
  char s[10];
  int num_line;

  printf("Numero de Linea: ");
  gets(s);
  num_line = atoi(s);

  info = Busca_Line(num_line);
  if(info){
    if(pent_list==info){
      pent_list = info->sig;
	if(pent_list) pent_list->ant = NULL;
	else uent_list = NULL;

    }
    else{
       info->ant->sig=info->sig;
       if(info!=uent_list)
	  info->sig->ant=info->ant;
       else
	  uent_list = info->ant;
    }
    free(info);
    Ajustar(num_line+1, -1);
  }
}

void Cargar_Arch(char *Nom_Arch)
{
  int tsize, cta_line;
  struct Ed_Line *info, *tmp;
  char *pt_text;
  FILE *_archivo;

  if((_archivo = fopen(Nom_Arch, "r"))==NULL){
     if((_archivo = fopen("Nom_Arch", "w"))== NULL){
	puts("No es posible crear el archivo");
	exit(0);
     }
  }

  while(pent_list){
    pt_text=pent_list->text_line;
    pent_list=pent_list->sig;
    free(pt_text);
  }

  puts("Cargando el Archivo");

  tsize = sizeof(struct Ed_Line);
  pent_list = (struct Ed_Line *)malloc(tsize);
  if(!pent_list){
    printf("Error de asignacion de Memoria\n");
    exit(0);
  }
  tmp=NULL;
  info = pent_list;
  pt_text = info->text_line;
  cta_line = 1;
  while((*pt_text=(char)getc(_archivo))!=EOF){
     *pt_text++;
     fgets(pt_text, 80, _archivo);
     info->num=cta_line++;
     info->sig=(struct Ed_Line *)malloc(tsize);
     if(info->sig==NULL){
       printf("Error de asignacion de Memoria\n");
       exit(0);
     }
     tmp=info;
     info=info->sig;
     info->ant=tmp;
     pt_text=info->text_line;
  }
  pent_list->ant=tmp->sig=NULL;
  uent_list=tmp;
  free(info);
  fclose(_archivo);
}

void Guardar_Arch(char *Nom_Arch)
{
  struct Ed_Line *info;
  char *pt_text;
  FILE *_archivo;

  if((_archivo=fopen(Nom_Arch, "w"))==NULL){
     printf("No se puede abrir el archivo\n");
     exit(1);
  }
  printf("\nSalvado el archivo\n");

  info=pent_list;
  while(info){
     pt_text = info->text_line;
     fputs(pt_text, _archivo);
     putc('\r', _archivo);
     putc('\n', _archivo);
     info = info->sig;
  }
  putc(EOF, _archivo);
  fclose(_archivo);
}

void Imprime_Arch()
{
 printf("Prepare la Impresora y pulse una tecla para continuar\n");

 printf("\nModulo no disponible\n");
}