]> git.llucax.com Git - z.facultad/75.06/emufs.git/commitdiff
* Bugfix en idx_get para saltar los registros no utilizados
authorRicardo Markiewicz <gazer.arg@gmail.com>
Fri, 16 Apr 2004 09:27:44 +0000 (09:27 +0000)
committerRicardo Markiewicz <gazer.arg@gmail.com>
Fri, 16 Apr 2004 09:27:44 +0000 (09:27 +0000)
 * Bugfix en tipo 3 para mandar mensajes por stderr
 * Agrego "compactar" en EMUFS
 * Agrego en GUI menu mantenimiento, que implementa el compactar y
 cambio de organizacion en archivos.

 Este ultimo no esta andando bien, fallan los leer de todos los tipos de datos.
 Como se puede ver en los archivos temporales, los .idx suelen quedar
 vacios en algunos casos! ... hay que revisar bien esas cosas.

emufs/emufs.h
emufs/idx.c
emufs/tipo3.c
emufs_gui/articulos.c
emufs_gui/articulos.h
emufs_gui/facturas.c
emufs_gui/facturas.h
emufs_gui/gui.c

index 9d8b17c56c2b4f73a7af7c184b719e5b735c8072..c2dab182c4baaf94855dcfb8825d5f2272f97b71 100644 (file)
@@ -123,6 +123,7 @@ typedef struct _emu_fs_t {
        EMUFS_REG_ID (*modificar_registro)(struct _emu_fs_t*, EMUFS_REG_ID, void*, EMUFS_REG_SIZE, int*); /**< Método para modificar un registro */
        int (*borrar_registro)(struct _emu_fs_t*, EMUFS_REG_ID); /**< Método para borrar un registro */
        EMUFS_Estadisticas (*leer_estadisticas)(struct _emu_fs_t *);
        EMUFS_REG_ID (*modificar_registro)(struct _emu_fs_t*, EMUFS_REG_ID, void*, EMUFS_REG_SIZE, int*); /**< Método para modificar un registro */
        int (*borrar_registro)(struct _emu_fs_t*, EMUFS_REG_ID); /**< Método para borrar un registro */
        EMUFS_Estadisticas (*leer_estadisticas)(struct _emu_fs_t *);
+       void (*compactar)(struct _emu_fs_t *);
        char *nombre; /**< Nombre del archivo */
 } EMUFS;
 
        char *nombre; /**< Nombre del archivo */
 } EMUFS;
 
index 701ba2597cdf0be3fd123c0dcaec0414045c7a18..8b4f969a922b1c2e3df7e99ad6abdb5a6f266202 100644 (file)
@@ -214,14 +214,18 @@ EMUFS_REG_ID *emufs_idx_get(EMUFS *emu, EMUFS_REG_ID *cant)
        count = 0;
        while (!feof(f_idx)) {
                if (fread(&reg, sizeof(EMUFS_IDX), 1, f_idx) != 1) continue;
        count = 0;
        while (!feof(f_idx)) {
                if (fread(&reg, sizeof(EMUFS_IDX), 1, f_idx) != 1) continue;
-               count++;
                /* TODO : Verificar errores :-D */
                /* TODO : Verificar errores :-D */
-               tmp = realloc(tmp, count);
-               tmp[count-1] = reg.id_reg;
+               if (reg.location != EMUFS_NOT_FOUND) {
+                       count++;
+                       tmp = realloc(tmp, count);
+                       tmp[count-1] = reg.id_reg;
+                       fprintf(stderr, "Nuevo registro de id = %lu\n", reg.id_reg);
+               }
        }
        fclose(f_idx);
 
        (*cant) = count;
        }
        fclose(f_idx);
 
        (*cant) = count;
+       fprintf(stderr, "Mando %d registros\n", count);
        return tmp;
 }
 
        return tmp;
 }
 
index 224c09665878699ddc50191c2b374f2b00a2a8d2..6375a7efd5001e8ddab4127a2c6389cf993237c8 100644 (file)
@@ -153,7 +153,7 @@ EMUFS_REG_ID emufs_tipo3_grabar_registro(EMUFS *emu, void *ptr, EMUFS_REG_SIZE t
        resto = emu->tam_bloque - sizeof(EMUFS_REG_ID);
        /* me devuelve el ID del bloque donde quepa un registro y el espacio libre en "fs"*/
        num_bloque = emufs_fsc_buscar_lugar(emu, emu->tam_reg+sizeof(EMUFS_REG_ID), &fs);
        resto = emu->tam_bloque - sizeof(EMUFS_REG_ID);
        /* me devuelve el ID del bloque donde quepa un registro y el espacio libre en "fs"*/
        num_bloque = emufs_fsc_buscar_lugar(emu, emu->tam_reg+sizeof(EMUFS_REG_ID), &fs);
-       printf("encontre lugar en %d\n", num_bloque);
+       fprintf(stderr, "encontre lugar en %d\n", num_bloque);
        /*si no hay bloques con suficiente espacio creo un bloque nuevo */
        if (num_bloque == -1) {
                if ( (file = fopen(name_f,"a+"))==NULL ) return -1; /*ERROR*/
        /*si no hay bloques con suficiente espacio creo un bloque nuevo */
        if (num_bloque == -1) {
                if ( (file = fopen(name_f,"a+"))==NULL ) return -1; /*ERROR*/
@@ -219,7 +219,7 @@ EMUFS_REG_ID emufs_tipo3_grabar_registro(EMUFS *emu, void *ptr, EMUFS_REG_SIZE t
                        /*grabo el id en el bloque*/
                        /*veo el espacio libre que queda*/ 
                        fs = emufs_fsc_get_fs(emu, num_bloque+i);
                        /*grabo el id en el bloque*/
                        /*veo el espacio libre que queda*/ 
                        fs = emufs_fsc_get_fs(emu, num_bloque+i);
-                       printf("el espacio libre del bloque %d es: %d\n", num_bloque+i, fs);
+                       fprintf(stderr, "el espacio libre del bloque %d es: %d\n", num_bloque+i, fs);
                        if (emu->tam_bloque-sizeof(EMUFS_REG_ID) < emu->tam_reg)
                                memcpy(bloque+sizeof(EMUFS_REG_ID),&ID_aux,sizeof(EMUFS_REG_ID));
                        else
                        if (emu->tam_bloque-sizeof(EMUFS_REG_ID) < emu->tam_reg)
                                memcpy(bloque+sizeof(EMUFS_REG_ID),&ID_aux,sizeof(EMUFS_REG_ID));
                        else
index af4536fbb9ee25dc228d28d348a8507ed38fed16..96f6b3d19158b3e6aa705c4192885dd6cde88836 100644 (file)
@@ -14,6 +14,11 @@ static t_Reg_Articulo *crear_nodo_articulo(EMUFS_REG_ID reg, unsigned int num);
 static int agregar_nodo_articulo(t_LstArticulos *lst, t_Reg_Articulo *nodo);
 static int eliminar_nodo_articulo(t_LstArticulos *lst, t_Reg_Articulo *nodo);
 
 static int agregar_nodo_articulo(t_LstArticulos *lst, t_Reg_Articulo *nodo);
 static int eliminar_nodo_articulo(t_LstArticulos *lst, t_Reg_Articulo *nodo);
 
+t_LstArticulos *art_get_lst()
+{
+       return lst_articulos;
+}
+
 int eliminar_nodo_articulo(t_LstArticulos *lst, t_Reg_Articulo *nodo)
 {
        if (nodo == NULL) return 0;
 int eliminar_nodo_articulo(t_LstArticulos *lst, t_Reg_Articulo *nodo)
 {
        if (nodo == NULL) return 0;
@@ -472,3 +477,73 @@ void *procesar_guardar_articulo(t_Articulo *src, EMUFS_REG_SIZE *size, t_LstArti
        return tmp;
 }
 
        return tmp;
 }
 
+void art_reformatear(int tipo, int tam_bloque, int tam_reg)
+{
+       EMUFS *nuevo, *old;
+       EMUFS_REG_ID *indices, id;
+       EMUFS_REG_SIZE indices_total, i, size;
+       t_Articulo art;
+       t_LstArticulos *lst_nueva;
+       int error;
+       char *save;
+
+       old = lst_articulos->fp;
+
+       /* Si el tipo es el mismo, no tengo que hacer nada! */
+       if (old->tipo == tipo) return;
+
+       fprintf(stderr, "Me prepado para cambiar de archivo\n");
+
+       /* Creo el nuevo file */
+       nuevo = emufs_crear("emufs_tmp", tipo, tam_bloque, sizeof(t_Articulo));
+       if (nuevo == NULL) {
+               fprintf(stderr, "ARCHIVO NUEVO NO CREADO\n");
+               return;
+       }
+
+       /* Creo la nueva lista */
+       lst_nueva = (t_LstArticulos *)malloc(sizeof(t_LstArticulos));
+       lst_nueva->primero = NULL;
+       lst_nueva->fp = nuevo;
+
+       /* Leo los indices del archivo viejo */
+       indices = emufs_idx_get(old, &indices_total);
+       if (indices == NULL) {
+               fprintf(stderr, "NO HAY INDICES!\n");
+               art_liberar(lst_nueva);
+               return;
+       }
+
+       for(i=0; i<indices_total; i++) {
+               fprintf(stderr, "Registro %lu de %lu\n", i, indices_total);
+               fprintf(stderr, "A leer : %lu\n", indices[i]);
+
+               save = old->leer_registro(old, indices[i], &size, &error);
+               fprintf(stderr, "Lei\n");
+               if (procesar_leer_articulo(&art, save, size, lst_articulos) == 1) {
+                       fprintf(stderr, "Procese\n");
+                       free(save);
+                       /* Lei un registro Ok. Lo salvo en el archivo nuevo */
+                       save = procesar_guardar_articulo(&art, &size, lst_nueva);
+                       fprintf(stderr, "Procese guardar\n");
+                       if (save) {
+                               id = nuevo->grabar_registro(nuevo, save, size, &error);
+                               fprintf(stderr, "Guarde\n");
+                               agregar_nodo_articulo(lst_nueva, crear_nodo_articulo(id, art.numero));
+                               free(save);
+                       }
+               }
+       }
+
+       art_liberar(lst_articulos);
+       lst_articulos = lst_nueva;
+
+       fprintf(stderr, "Listo. Renombre y me voy\n");
+       /* Muevo los archivos! */
+       /* TODO : Poner en otro lugar mas generico! */
+/*     rename("emufs_tmp.dat", "articulos.dat");
+       rename("emufs_tmp.idx", "articulos.idx");
+       rename("emufs_tmp.fsc", "articulos.fsc");
+       rename("emufs_tmp.did", "articulos.did");*/
+}
+
index 8d7ecedd0b8efd6ade1361ba371f05d7641f3a2f..432e85bab707ca309d84018da1067c3329c14092 100644 (file)
@@ -38,6 +38,7 @@ t_Articulo *art_obtener(t_LstArticulos *, const char *numero, EMUFS_REG_ID *id);
 void art_agregar(char *);
 void art_eliminar(char *);
 void art_modificar(char *);
 void art_agregar(char *);
 void art_eliminar(char *);
 void art_modificar(char *);
-
+t_LstArticulos *art_get_lst();
+void art_reformatear(int tipo, int tam_bloque, int tam_reg);
 #endif
 
 #endif
 
index d0c0428895ff75abbc13eac55d99e756cd30f117..ec87770eba0c0424012395c95402bb46a86cca7e 100644 (file)
@@ -12,6 +12,11 @@ int eliminar_nodo_factura(t_LstFacturas *lst, t_Reg_Factura *nodo);
 static t_Item *leer_items(xmlNode *, int *cant, int size);
 static char *leer_nota(xmlNode *);
 
 static t_Item *leer_items(xmlNode *, int *cant, int size);
 static char *leer_nota(xmlNode *);
 
+t_LstFacturas *fact_get_lst()
+{
+       return lst_facturas;
+}
+
 /* Hack! ... Si no existe propiedad retorna "" */
 char *xml_get_prop(xmlNode *node, char *nombre)
 {
 /* Hack! ... Si no existe propiedad retorna "" */
 char *xml_get_prop(xmlNode *node, char *nombre)
 {
@@ -190,6 +195,8 @@ t_LstFacturas *fact_cargar(const char *filename, int tipo, int tam_bloque)
                                                id = tmp->fp->grabar_registro(tmp->fp, save, size, &error);
                                                id_texto = tmp->fp_texto->grabar_registro(tmp->fp_texto, fact.nota, 400, &error);
                                                agregar_nodo_factura(tmp, crear_nodo_factura(id, id_texto, fact.numero));
                                                id = tmp->fp->grabar_registro(tmp->fp, save, size, &error);
                                                id_texto = tmp->fp_texto->grabar_registro(tmp->fp_texto, fact.nota, 400, &error);
                                                agregar_nodo_factura(tmp, crear_nodo_factura(id, id_texto, fact.numero));
+                                               if (fact.items) free(fact.items);
+                                               if (fact.nota) free(fact.nota);
                                                free(save);
                                        }
                                }
                                                free(save);
                                        }
                                }
@@ -228,7 +235,7 @@ int fact_liberar(t_LstFacturas *l)
        return 0;
 }
 
        return 0;
 }
 
-t_Factura *fact_buscar(t_LstFacturas *lst, int numero)
+t_Factura *fact_buscar(t_LstFacturas *lst, int numero, EMUFS_REG_ID *id, EMUFS_REG_ID *id_texto)
 {
        t_Factura *fact;
        t_Reg_Factura *reg;
 {
        t_Factura *fact;
        t_Reg_Factura *reg;
@@ -241,10 +248,16 @@ t_Factura *fact_buscar(t_LstFacturas *lst, int numero)
        reg = lst->primero;
        while (reg) {
                if (reg->numero == numero) {
        reg = lst->primero;
        while (reg) {
                if (reg->numero == numero) {
+                       size = 0;
+                       fprintf(stderr, "Leer me dice que %lu\n", size);
                        leo = lst->fp->leer_registro(lst->fp, reg->num_reg, &size, &error);
                        leo = lst->fp->leer_registro(lst->fp, reg->num_reg, &size, &error);
+                       fprintf(stderr, "Leer me dice que %lu\n", size);
                        if (leo != NULL) {
                                fact = (t_Factura *)malloc(sizeof(t_Factura));
                                procesar_leer_factura(fact, leo, size, lst);
                        if (leo != NULL) {
                                fact = (t_Factura *)malloc(sizeof(t_Factura));
                                procesar_leer_factura(fact, leo, size, lst);
+                               (*id) = reg->num_reg;
+                               (*id_texto) = reg->texto_reg;
+                               free(leo);
                        }
                        break;
                }
                        }
                        break;
                }
@@ -253,7 +266,7 @@ t_Factura *fact_buscar(t_LstFacturas *lst, int numero)
        return fact;
 }
 
        return fact;
 }
 
-t_Factura *fact_form_buscar(WINDOW *win, EMUFS_REG_ID *id)
+t_Factura *fact_form_buscar(WINDOW *win, EMUFS_REG_ID *id, EMUFS_REG_ID *id_texto)
 {
        t_Form *form;
        t_Factura *fact;
 {
        t_Form *form;
        t_Factura *fact;
@@ -261,19 +274,58 @@ t_Factura *fact_form_buscar(WINDOW *win, EMUFS_REG_ID *id)
        form = form_crear(win);
        form_agregar_widget(form, INPUT, "Numero de Factura", 8, "");
        form_ejecutar(form, 1,1);
        form = form_crear(win);
        form_agregar_widget(form, INPUT, "Numero de Factura", 8, "");
        form_ejecutar(form, 1,1);
-       fact = fact_buscar(lst_facturas, form_obtener_valor_int(form, "Numero de Factura"));
+       fact = fact_buscar(lst_facturas, form_obtener_valor_int(form, "Numero de Factura"), id, id_texto);
        form_destruir(form);
 
        return fact;
 }
 
        form_destruir(form);
 
        return fact;
 }
 
+void fact_eliminar(char *s)
+{
+       WINDOW *win;
+       t_Factura *fact;
+       t_Reg_Factura *nodo;
+       EMUFS_REG_ID id;
+                                                                       
+       win = newwin(LINES-4, COLS-2, 2, 1);
+       box(win, 0, 0);
+       
+       fact = fact_form_buscar(win, &id, &id);
+
+       if (fact == NULL) {
+               wattron(win, COLOR_PAIR(COLOR_YELLOW));
+               mvwaddstr(win, 2, 1, "No existe artículo con ese código. Abortando!");
+               wattroff(win, COLOR_PAIR(COLOR_YELLOW));
+               wrefresh(win);
+               getch();
+               werase(win);
+               wrefresh(win);
+               delwin(win);
+               return;
+       }
+
+       nodo = lst_facturas->primero;
+       while (nodo) {
+               if (nodo->numero == fact->numero) {
+                       lst_facturas->fp->borrar_registro(lst_facturas->fp, nodo->num_reg);
+                       lst_facturas->fp_texto->borrar_registro(lst_facturas->fp_texto, nodo->texto_reg);
+                       eliminar_nodo_factura(lst_facturas, nodo);
+                       break;
+               }
+               nodo = nodo->sig;
+       }
+
+       free(fact->items);
+       free(fact);
+}
+
 void fact_modificar(char *s)
 {
        WINDOW *win, *items;
        t_Form *form;
        t_Factura *fact;
        /*EMUFS_REG_SIZE size;*/
 void fact_modificar(char *s)
 {
        WINDOW *win, *items;
        t_Form *form;
        t_Factura *fact;
        /*EMUFS_REG_SIZE size;*/
-       EMUFS_REG_ID id; /*, id_texto;*/
+       EMUFS_REG_ID id, id_texto;
 /*     int y_actual, cant, error;*/
        char tmp_str[10];
 
 /*     int y_actual, cant, error;*/
        char tmp_str[10];
 
@@ -281,9 +333,14 @@ void fact_modificar(char *s)
        win = newwin(LINES-4, COLS-2, 2, 1);
        box(win, 0, 0);
        
        win = newwin(LINES-4, COLS-2, 2, 1);
        box(win, 0, 0);
        
-       fact = fact_form_buscar(win, &id);
+       fact = fact_form_buscar(win, &id, &id_texto);
 
        if (fact == NULL) {
 
        if (fact == NULL) {
+               wattron(win, COLOR_PAIR(COLOR_YELLOW));
+               mvwaddstr(win, 2, 1, "No existe artículo con ese código. Abortando!");
+               wattroff(win, COLOR_PAIR(COLOR_YELLOW));
+               wrefresh(win);
+               getch();
                werase(win);
                wrefresh(win);
                delwin(win);
                werase(win);
                wrefresh(win);
                delwin(win);
@@ -507,9 +564,68 @@ void *procesar_guardar_factura(t_Factura *f, t_LstFacturas *lst, EMUFS_REG_SIZE
 
 static int procesar_leer_factura(t_Factura *dst, void *src, EMUFS_REG_SIZE size, t_LstFacturas *lst)
 {
 
 static int procesar_leer_factura(t_Factura *dst, void *src, EMUFS_REG_SIZE size, t_LstFacturas *lst)
 {
+       char *ini, *fin;
+
        switch (lst->fp->tipo) {
                case T1:
                case T2:
        switch (lst->fp->tipo) {
                case T1:
                case T2:
+                       ini = (char *)src;
+                       /* Copio los campos numericos, muy facil:-) */
+                       memcpy(&dst->numero, ini, sizeof(int));
+                       ini+=sizeof(int);
+                       
+                       memcpy(&dst->procdoi, ini, sizeof(float));
+                       ini+=sizeof(float);
+
+                       memcpy(&dst->numero_remito, ini, sizeof(int));
+                       ini+=sizeof(int);
+                       
+                       memcpy(&dst->cant_items, ini, sizeof(int));
+                       ini+=sizeof(int);
+
+                       /* Ahora empieza el juego */
+                       /* Los \0 son los delimitadores de campo! */
+                       fin = ini;
+                       while (*fin!='\0') fin++;
+                       memcpy(dst->emision, ini, fin-ini+1);
+                       
+                       ini = fin+1;
+                       fin = ini;
+                       while (*fin!='\0') fin++;
+                       memcpy(dst->vencimiento, ini, fin-ini+1);
+                       
+                       ini = fin+1;
+                       fin = ini;
+                       while (*fin!='\0') fin++;
+                       memcpy(dst->estado, ini, fin-ini+1);
+                       
+                       ini = fin+1;
+                       fin = ini;
+                       while (*fin!='\0') fin++;
+                       memcpy(dst->fp, ini, fin-ini+1);
+                       
+                       ini = fin+1;
+                       fin = ini;
+                       while (*fin!='\0') fin++;
+                       memcpy(dst->ctacte, ini, fin-ini+1);
+                       
+                       ini = fin+1;
+                       fin = ini;
+                       while (*fin!='\0') fin++;
+                       memcpy(dst->cheque, ini, fin-ini+1);
+
+                       if (dst->cant_items > 0) {
+                               /* Ahora tengo que cargar los items */
+                               dst->items = (t_Item *)malloc(sizeof(t_Item)*dst->cant_items);
+
+                               ini = fin+1;
+                               fprintf(stderr, "trabajo con 1 -> %lu\n", size);
+                               fin = (char *)src+size;
+                               memcpy(dst->items, ini, fin-ini);
+                       } else {
+                               dst->items = NULL;
+                       }
+
                        return 0;
                case T3:
                        /* Se que tengo 10 items */
                        return 0;
                case T3:
                        /* Se que tengo 10 items */
index cdf92bc8c5afbbe80f12211972802da1084237ae..c43a104c48221290c64f6089f0a61972a135cbcf 100644 (file)
@@ -54,6 +54,9 @@ int fact_liberar(t_LstFacturas *l);
 
 void fact_agregar(char *s);
 void fact_modificar(char *s);
 
 void fact_agregar(char *s);
 void fact_modificar(char *s);
+void fact_eliminar(char *s);
+
+t_LstFacturas *fact_get_lst();
 
 #endif
 
 
 #endif
 
index 99418b83738486226e024b298c7000839d9848ba..5346b6c9b726bb0b040b01a8226ce661d9c4461d 100644 (file)
@@ -19,6 +19,8 @@ static void finish(int sig);
 int main_menu();
 void menu_articulos();
 void menu_facturas();
 int main_menu();
 void menu_articulos();
 void menu_facturas();
+void menu_mantenimiento();
+void preguntar_nuevo_tipo(int *tipo, int *tam_bloque, int *tam_reg);
 
 /* cuadro de msg. w y h son de la ventana padre */
 WINDOW *msg_box(WINDOW *win, int w, int h, const char *format, ...);
 
 /* cuadro de msg. w y h son de la ventana padre */
 WINDOW *msg_box(WINDOW *win, int w, int h, const char *format, ...);
@@ -136,7 +138,7 @@ int main(int argc, char *argv[])
        dialog = msg_box(stdscr, COLS, LINES, "Generando archivos ...");
        if (argc == 4) {
                art_cargar(argv[1], atoi(argv[2]), atoi(argv[3]));
        dialog = msg_box(stdscr, COLS, LINES, "Generando archivos ...");
        if (argc == 4) {
                art_cargar(argv[1], atoi(argv[2]), atoi(argv[3]));
-               if (!fact_cargar("facturas.xml", 3, 400))
+               if (!fact_cargar("facturas.xml", 1, 400))
                        fprintf(stderr, "ERROR CARGANDO FACTURAS\n");
        } else
                art_cargar(NULL, -1, -1);
                        fprintf(stderr, "ERROR CARGANDO FACTURAS\n");
        } else
                art_cargar(NULL, -1, -1);
@@ -160,7 +162,9 @@ int main(int argc, char *argv[])
                                delwin(dialog);
                                refresh();
                        break;
                                delwin(dialog);
                                refresh();
                        break;
-               //      case 3:
+                       case 5:
+                               menu_mantenimiento();
+                       break;
                        case 6:
                                fin = 1;
                        break;
                        case 6:
                                fin = 1;
                        break;
@@ -194,7 +198,7 @@ void menu_facturas()
        items[0] = new_item(opciones[0], "Crear una nueva factura.");
        set_item_userptr(items[0], fact_agregar);
        items[1] = new_item(opciones[1], "Eliminar una factura existente.");
        items[0] = new_item(opciones[0], "Crear una nueva factura.");
        set_item_userptr(items[0], fact_agregar);
        items[1] = new_item(opciones[1], "Eliminar una factura existente.");
-/*     set_item_userptr(items[1], art_eliminar); */
+       set_item_userptr(items[1], fact_eliminar);
        items[2] = new_item(opciones[2], "Modificar una factura existente.");
        set_item_userptr(items[2], fact_modificar); 
        items[3] = new_item(opciones[3], "Volver al menu anterior.");
        items[2] = new_item(opciones[2], "Modificar una factura existente.");
        set_item_userptr(items[2], fact_modificar); 
        items[3] = new_item(opciones[3], "Volver al menu anterior.");
@@ -261,6 +265,7 @@ void menu_facturas()
        free_item(items[2]);
        free_item(items[3]);
        free_menu(menu);
        free_item(items[2]);
        free_item(items[3]);
        free_menu(menu);
+       free(items);
 }
 void menu_articulos()
 {
 }
 void menu_articulos()
 {
@@ -347,6 +352,7 @@ void menu_articulos()
        free_item(items[2]);
        free_item(items[3]);
        free_menu(menu);
        free_item(items[2]);
        free_item(items[3]);
        free_menu(menu);
+       free(items);
 }
 
 int main_menu()
 }
 
 int main_menu()
@@ -435,6 +441,7 @@ int main_menu()
        free_item(items[5]);
        free_item(items[6]);
        free_menu(menu);
        free_item(items[5]);
        free_item(items[6]);
        free_menu(menu);
+       free(items);
 
        return opcion;
 }
 
        return opcion;
 }
@@ -477,3 +484,187 @@ void msg_box_free(WINDOW *padre, WINDOW *win)
        wrefresh(padre);
 }
 
        wrefresh(padre);
 }
 
+void menu_mantenimiento()
+{
+       WINDOW *menu_win, *dlg;
+       MENU *menu;
+       ITEM **items;
+       int c, salir, nuevo_tipo, nuevo_tam_bloque, nuevo_tam_registro;
+       char *opciones[] = {
+                                       "Compactar Articulos",
+                                       "Compactar Facturas",
+                                       "Compactar Notas",
+                                       "Cambiar tipo Archivo Articulos",
+                                       "Cambiar tipo Archivo Facturas",
+                                       "Cambiar tipo Archivo Notas",
+                                       "Volver"
+       };
+
+       items = (ITEM **)calloc(8, sizeof(ITEM *));
+
+       items[0] = new_item(opciones[0], "Elimina espacio no utilizado.");
+       items[1] = new_item(opciones[1], "Elimina espacio no utilizado.");
+       items[2] = new_item(opciones[2], "Elimina espacio no utilizado.");
+       items[3] = new_item(opciones[3], "Permite cambiar el tipo del archivo.");
+       items[4] = new_item(opciones[4], "Permite cambiar el tipo del archivo.");
+       items[5] = new_item(opciones[5], "Permite cambiar el tipo del archivo.");
+       items[6] = new_item(opciones[6], "Volver al menu anterior.");
+       items[7] = NULL;
+
+       menu = new_menu((ITEM **)items);
+       menu_win = newwin(12, COLS-2, 3, 1);
+       keypad(menu_win, TRUE);
+       set_menu_mark(menu, " > ");
+       set_menu_win(menu, menu_win);
+       set_menu_sub(menu, derwin(menu_win, 8, COLS-4, 3, 1));
+
+       box(menu_win, 0, 0);
+       mvwaddch(menu_win, 2, 0, ACS_LTEE);
+       mvwhline(menu_win, 2, 1, ACS_HLINE, COLS-3);
+       mvwaddch(menu_win, 2, COLS-3, ACS_RTEE);
+       wattron(menu_win, COLOR_PAIR(COLOR_RED));
+       mvwaddstr(menu_win, 1, 1, "Menu Mantenimiento");
+       wattroff(menu_win, COLOR_PAIR(COLOR_RED));
+       post_menu(menu);
+       wrefresh(menu_win);
+
+       curs_set(0);
+       salir = 0;
+       while((!salir) && (c = getch()) != KEY_F(3)) {
+               switch(c) {
+                       case KEY_DOWN:
+                               menu_driver(menu, REQ_DOWN_ITEM);
+                               break;
+                       case KEY_UP:
+                               menu_driver(menu, REQ_UP_ITEM);
+                       break;
+                       case 13:
+                       case 10: 
+                       {
+                               ITEM *cur;
+
+                               cur = current_item(menu);
+                               if (strcmp(item_name(cur), opciones[6]) == 0) {
+                                       salir = 1;
+                               } else {
+                                       if (strcmp(item_name(cur), opciones[0]) == 0) {
+                                               art_get_lst()->fp->compactar(art_get_lst()->fp);
+                                       }
+                                       if (strcmp(item_name(cur), opciones[1]) == 0) {
+                                               fact_get_lst()->fp->compactar(fact_get_lst()->fp);
+                                       }
+                                       if (strcmp(item_name(cur), opciones[2]) == 0) {
+                                               fact_get_lst()->fp_texto->compactar(fact_get_lst()->fp_texto);
+                                       }
+                                       if (strcmp(item_name(cur), opciones[3]) == 0) {
+                                               unpost_menu(menu);
+                                               nuevo_tam_registro = -1; /* No permito cambiar el tamaño de registro */
+                                               preguntar_nuevo_tipo(&nuevo_tipo, &nuevo_tam_bloque, &nuevo_tam_registro);
+                                               dlg = msg_box(stdscr, COLS, LINES, "Cambiando el formato de archivo .... Aguarde");
+                                               art_reformatear(nuevo_tipo, nuevo_tam_bloque, nuevo_tam_registro);
+                                               msg_box_free(stdscr, dlg);
+                                               box(menu_win, 0, 0);
+                                               post_menu(menu);
+                                       }
+                                       if (strcmp(item_name(cur), opciones[4]) == 0) {
+                                               unpost_menu(menu);
+                                               nuevo_tam_registro = 0;
+                                               preguntar_nuevo_tipo(&nuevo_tipo, &nuevo_tam_bloque, &nuevo_tam_registro);
+                                               box(menu_win, 0, 0);
+                                               post_menu(menu);
+                                       }
+                                       if (strcmp(item_name(cur), opciones[5]) == 0) {
+                                               unpost_menu(menu);
+                                               nuevo_tam_registro = -2;
+                                               preguntar_nuevo_tipo(&nuevo_tipo, &nuevo_tam_bloque, &nuevo_tam_registro);
+                                               box(menu_win, 0, 0);
+                                               post_menu(menu);
+                                       }
+                               }
+                       }
+               }
+               wrefresh(menu_win);
+       }       
+       curs_set(1);
+       
+       unpost_menu(menu);
+       delwin(menu_win);
+       free_item(items[0]);
+       free_item(items[1]);
+       free_item(items[2]);
+       free_item(items[3]);
+       free_menu(menu);
+
+       free(items);
+}
+
+void preguntar_nuevo_tipo(int *tipo, int *tam_bloque, int *tam_reg)
+{
+       WINDOW *win;
+       t_Form *form;
+       char *s;
+       int n, is_ok;
+
+       win = newwin(LINES/2, COLS/2, LINES/4, COLS/4);
+       box(win, 0, 0);
+
+       form = form_crear(win);
+       form_agregar_widget(form, RADIO, "Tipo de archivo", 3, "T1,T2,T3");
+       form_ejecutar(form, 1,1);
+
+       s = form_obtener_valor_char(form, "Tipo de archivo");
+       if (strcmp(s, "T1") == 0) n = T1;
+       if (strcmp(s, "T2") == 0) n = T2;
+       if (strcmp(s, "T3") == 0) n = T3;
+
+       form_destruir(form);
+
+       werase(win);
+       box(win, 0, 0);
+       wrefresh(win);
+
+       (*tipo) = n;
+       switch (n) {
+               case T1:
+                       form = form_crear(win);
+                       form_agregar_widget(form, INPUT, "Tamaño de bloque", 8, "");
+                       is_ok = 0;
+                       do {
+                               form_set_valor(form, "Tamaño de bloque", "");
+                               form_ejecutar(form, 1,1);
+                               if (form_obtener_valor_int(form, "Tamaño de bloque") > 0) is_ok = 1;
+                       } while (!is_ok);
+                       (*tam_bloque) = form_obtener_valor_int(form, "Tamaño de bloque");
+                       form_destruir(form);
+               break;
+               case T2:
+                       break;
+               case T3:
+                       if (((*tam_reg) != -1) && ((*tam_reg) != -2)) {
+                               mvwaddstr(win, LINES/2-3, 1, "Nota: El tamaño de registro puede");
+                               mvwaddstr(win, LINES/2-2, 1, "llegar a ser redondeado por el sistema.");
+                       }
+                       form = form_crear(win);
+                       form_agregar_widget(form, INPUT, "Tamaño de bloque", 8, "");
+                       if ((*tam_reg) != -1)
+                               form_agregar_widget(form, INPUT, "Tamaño de registro", 8, "");
+                       is_ok = 0;
+                       do {
+                               form_set_valor(form, "Tamaño de bloque", "");
+                               if ((*tam_reg) != -1)
+                                       form_set_valor(form, "Tamaño de registro", "");
+                               form_ejecutar(form, 1,1);
+                               if (form_obtener_valor_int(form, "Tamaño de bloque") > 0) is_ok = 1;
+                               if ((*tam_reg) != -1) {
+                                       if (form_obtener_valor_int(form, "Tamaño de registro") > 0) is_ok = 1; else is_ok = 0;
+                               }
+                       } while (!is_ok);
+                       (*tam_bloque) = form_obtener_valor_int(form, "Tamaño de bloque");
+                       if ((*tam_reg) != -1)
+                               (*tam_reg) = form_obtener_valor_int(form, "Tamaño de registro");
+                       form_destruir(form);
+       }
+       werase(win);
+       wrefresh(win);
+       delwin(win);
+}