File:  [Repository ATC2] / ADD_ver_10 / Source Code / Source Files / BasesDatos.c
Revision 1.2: download - view: text, annotated - select for diffs
Tue Feb 28 14:54:21 2006 UTC (18 years, 6 months ago) by rico
Branches: MAIN
CVS tags: HEAD
*** empty log message ***

/********************************************************************/
/*  BasesDatos.c                                                    */
/*                                                                  */
/*                                                                  */
/*  Copyright (c) 1997-2006 Rafael Rico      (rafael.rico@uah.es)   */
/*                                                                  */
/*  Este fichero forma parte de ADD                                 */
/*  (Analizador de Dependencias de Datos)                           */
/*  Version 5.10.                                                   */
/*                                                                  */
/*                                                                  */
/*  ADD es software libre. Puede redistribuirlo y/o modificarlo     */
/*  bajo los términos de la Licencia Pública General de GNU         */
/*  según es publicada por la Free Software Foundation, bien bajo   */
/*  la versión 2 de dicha Licencia o bien (según su elección)       */
/*  bajo cualquier versión posterior.                               */
/*                                                                  */
/*  ADD se distribuye con la esperanza de que sea útil,             */
/*  pero SIN NINGUNA GARANTÍA, incluso sin la garantía MERCANTIL    */
/*  implícita y sin garantizar la CONVENIENCIA PARA UN PROPÓSITO    */
/*  PARTICULAR. Véase la Licencia Pública General de GNU para       */
/*  más detalles.                                                   */
/*                                                                  */
/*  Debería haber recibido una copia de la Licencia Pública General */
/*  junto con ADD. Si no ha sido así, escriba a la Free Software    */
/*  Foundation, Inc., 51 Franklin St, Fifth Floor,                  */
/*  Boston, MA  02110-1301  EEUU.                                   */
/*                                                                  */
/*  -------------------------- Historia --------------------------- */
/*                                                                  */
/*  $Id: BasesDatos.c,v 1.2 2006/02/28 14:54:21 rico Exp $                                                            */
/*                                                                  */
/*  Revisión 1.2. 01/2006                                           */
/*  Se añade la licencia GPL y documentación en estilo Javadoc      */
/*                                                                  */
/*  Revisión 1.1. 09/2005                                           */
/*  Versión inicial                                                 */
/*                                                                  */
/********************************************************************/

/******************************************************************************/
/* MÓDULO: BasesDatos.c                                                       */
/*                                                                            */
/* Este módulo carga en memoria la base de datos que modela la arquitectura   */
/* del repertorio IA16 (tabla de nemónicos y tabla de ubicaciones de datos)   */
/* y la tabla de tiempos de un procesador en ciclos (tiempo de ejecución de   */
/* operaciones, tiempo de acceso a operandos y tiempo de cómputo de           */
/* direcciones de memoria.                                                    */
/******************************************************************************/
/* Fecha: 19 de septiembre de 2005                                            */
/******************************************************************************/

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

#include "defines.h"
#include "tipos.h"
#include "basesdatos.h"


/* configuración */
extern struct argumentos configuracion;

/* bases de datos */
extern unsigned int num_nemonicos;
extern operacion *nemonicos;
extern unsigned int num_simbolos;
extern operando *simbolos;
extern unsigned int num_tiempos;
extern tiempo *ciclos;


void CargarArquitecturaIA16Nemonicos(FILE *f_ia16_nemos)
{
    unsigned int i;
    char linea[MAX_LINE];
    char *registro, *campo;
    char mensaje[MAX_LINE];


    sprintf(mensaje, "[CargarArquitecturaIA16Nemonicos] Cargando base de datos del repertorio IA16...");
    Notificar(mensaje, NO_ERROR, ECO_NO);

    /* salto los comentarios */
    do fgets (linea, MAX_LINE, f_ia16_nemos); while (linea[0]=='#');

    /* leo el número de registros (primera línea con información) */
    num_nemonicos = atoi(linea);

    sprintf(mensaje, "[CargarArquitecturaIA16Nemonicos] Reservo memoria para %d registros", num_nemonicos);
    Notificar(mensaje, NO_ERROR, ECO_NO);

    /* malloc reserva memoria; calloc reserva memoria y rellena con 0's */
    /* calloc es más lenta pero me asegura que los valores numéricos van */
    /* a ser 0 y las cadenas van a ser vacías */
    nemonicos = calloc(num_nemonicos, sizeof(operacion));
    if (nemonicos == NULL)
    {
        sprintf(mensaje, "[CargarArquitecturaIA16Nemonicos] Memoria insuficiente");
        Notificar(mensaje, ERROR_SALIR, ECO_NO);
        /* el programa finaliza si no hay memoria suficiente */
    }

    sprintf(mensaje, "[CargarArquitecturaIA16Nemonicos] Cargando datos de nemónicos...");
    Notificar(mensaje, NO_ERROR, ECO_NO);

    i = 0;
    while(i<num_nemonicos)
    {
        /* salto los comentarios */
        do fgets (linea, MAX_LINE, f_ia16_nemos); while(linea[0]=='#');

        /* hago un barrido de la línea hasta encontrar el final de línea */
        /* cada ocurrencia de '\t' la cambio por '\0' para convertirlo   */
        /* en una cadena separada (campo)                                */

        /* el puntero 'registro' me permite moverme por la línea */
        /* el puntero 'campo' se encarga se señalar el comienzo de los campos */
        registro = linea;
        campo = linea;
        while(*++registro!='\0')
        {
            if(*registro=='\t')
            {
                *registro = '\0';    /* finalizo un campo */
                /* campo nemonico */
                if(campo[0]!='-') strcpy(nemonicos[i].nemonico, campo);
                else
                {
                    switch(campo[1])
                    {
                        case 't':    /* tipo de nemonico */
                        nemonicos[i].tipo = atoi(campo+3);
                        break;

                        case '1':    /* modo del operando 1 (destino) explícito */
                        nemonicos[i].modo_op1 = atoi(campo+3);
                        break;

                        case '2':    /* modo del operando 2 (fuente) explícito */
                        nemonicos[i].modo_op2 = atoi(campo+3);
                        break;

                        case 'e':   /* implícitos escritos */
                        strcpy(nemonicos[i].implicitos_escritos, campo+3);
                        break;

                        case 'l':   /* implícitos leidos */
                        strcpy(nemonicos[i].implicitos_leidos, campo+3);
                        break;

                        default:
                        /* mandar un error a un fichero de log */
                        break;
                    }
                }
                campo = registro+1;    /* hago que apunte al siguiente */
            }
        }

        /* echo */
        /* printf("%3d %10s %d %d\t%15s\t%30s\n", i, operaciones[i].nemonico, 
                     operaciones[i].modo_fuente, operaciones[i].modo_destino, 
                     operaciones[i].implicitos_leidos, 
                     operaciones[i].implicitos_escritos); */
        /* _getch(); */

        i++;    /* índice del siguiente registro */
    }

    sprintf(mensaje, "[CargarArquitecturaIA16Nemonicos] La tabla de nemónicos se ha cargado con éxito");
    Notificar(mensaje, NO_ERROR, ECO_NO);
}


void CargarArquitecturaIA16Simbolos(FILE *f_ia16_ubis)
{
    unsigned int i;
    char linea[MAX_LINE];
    char *campo;
    char mensaje[MAX_LINE];

    sprintf(mensaje, "[CargarArquitecturaIA16Simbolos] Cargando base de datos del repertorio IA16...");
    Notificar(mensaje, NO_ERROR, ECO_NO);

    /* salto los comentarios */
    do fgets (linea, MAX_LINE, f_ia16_ubis); while (linea[0]=='#');

    /* leo el número de registros (primera línea con información) */
    num_simbolos = atoi(linea);

    sprintf(mensaje, "[CargarArquitecturaIA16Simbolos] Reservo memoria para %d registros", num_simbolos);
    Notificar(mensaje, NO_ERROR, ECO_NO);

    /* malloc reserva memoria; calloc reserva memoria y rellena con 0's */
    /* calloc es más lenta pero me asegura que los valores numéricos van */
    /* a ser 0 y las cadenas van a ser vacías */
    simbolos = calloc(num_simbolos, sizeof(operando));
    if (simbolos == NULL)
    {
        sprintf(mensaje, "[CargarArquitecturaIA16Simbolos] Memoria insuficiente");
        Notificar(mensaje, ERROR_SALIR, ECO_NO);
        /* el programa finaliza si no hay memoria suficiente */
    }

    sprintf(mensaje, "[CargarArquitecturaIA16Simbolos] Cargando datos de símbolos...");
    Notificar(mensaje, NO_ERROR, ECO_NO);

    i = 0;
    while(i<num_simbolos)
    {
        /* salto los comentarios */
        do fgets (linea, MAX_LINE, f_ia16_ubis); while(linea[0]=='#');

        campo = strtok(linea, "\t\n");    /* el separador de campos es '\t' */
                                          /* añado '\n' porque al final de linea */
                                          /* tengo ese caracter y lo toma por un campo */
        while(campo != NULL)
        {
            /* trato el campo capturado por la función strtok */
            /* campo símbolo */
            if(campo[0]!='-') strcpy(simbolos[i].simbolo, campo);
            else
            {
                switch(campo[1])
                {
                    case 'd':    /* dependencias */
                    strcpy(simbolos[i].dependencias, campo+3);
                    break;

                    case 's':    /* segmento por defecto */
                    simbolos[i].segmento = atoi (campo+3);
                    break;

                    case 't':    /* tipo de ubicación */
                    simbolos[i].tipo = atoi (campo+3);
                    break;

                    default:
                    /* mandar un error a un fichero de log */
                    break;
                }
            }
            /* capturo el siguiente campo */
            campo = strtok(NULL, "\t\n");
        }
        
        /* echo */
        /* printf(); */
        /* _getch(); */

        i++;    /* índice del siguiente registro */
    }

    sprintf(mensaje, "[CargarArquitecturaIA16Simbolos] La tabla de símbolos se ha cargado con éxito");
    Notificar(mensaje, NO_ERROR, ECO_NO);
}


void CargarTiemposProcesador(FILE *f_procesador)
{
    unsigned int i;
    char linea[MAX_LINE];
    char *campo;
    char mensaje[MAX_LINE];

    sprintf(mensaje, "[CargarTiemposProcesador] Cargando base de datos del procesador...");
    Notificar(mensaje, NO_ERROR, ECO_NO);

    /* salto los comentarios */
    do fgets (linea, MAX_LINE, f_procesador); while (linea[0]=='#');

    /* leo el número de registros (primera línea con información) */
    num_tiempos = atoi(linea);

    sprintf(mensaje, "[CargarTiemposProcesador] Reservo memoria para %d registros", num_tiempos);
    Notificar(mensaje, NO_ERROR, ECO_NO);

    /* malloc reserva memoria; calloc reserva memoria y rellena con 0's */
    /* calloc es más lenta pero me asegura que los valores numéricos van */
    /* a ser 0 y las cadenas van a ser vacías */
    ciclos = calloc(num_tiempos, sizeof(tiempo));
    if (ciclos == NULL)
    {
        sprintf(mensaje, "[CargarTiemposProcesador] Memoria insuficiente");
        Notificar(mensaje, ERROR_SALIR, ECO_NO);
        /* el programa finaliza si no hay memoria suficiente */
    }

    sprintf(mensaje, "[CargarTiemposProcesador] Cargando datos de tiempos...");
    Notificar(mensaje, NO_ERROR, ECO_NO);

    i = 0;
    while(i<num_tiempos)
    {
        /* salto los comentarios */
        do fgets (linea, MAX_LINE, f_procesador); while(linea[0]=='#');

        campo = strtok(linea, "\t\n");    /* el separador de campos es '\t' */
                                          /* añado '\n' porque al final de linea */
                                          /* tengo ese caracter y lo toma por un campo */
        while(campo != NULL)
        {
            /* trato el campo capturado por la función strtok */
            /* campo identificador */
            if(campo[0]!='-') strcpy(ciclos[i].identificador, campo);
            else
            {
                switch(campo[1])
                {
                    case 'c':    /* dependencias */
                    ciclos[i].ciclos = atoi (campo+3);
                    break;

                    default:
                    /* mandar un error a un fichero de log */
                    break;
                }
            }
            /* capturo el siguiente campo */
            campo = strtok(NULL, "\t\n");
        }

        /* echo */
        /* printf(); */
        /* _getch(); */
        
        i++;    /* índice del siguiente registro */
    }

    sprintf(mensaje, "[CargarTiemposProcesador] La tabla de tiempos se ha cargado con éxito");
    Notificar(mensaje, NO_ERROR, ECO_NO);
}


void CargarArquitecturaIA16()
{
    FILE *f_ia16_nemos, *f_ia16_ubis;
    char mensaje[MAX_LINE];

    
    /* abro el fichero de nemónicos de la arquitectura del repertorio */
    if((f_ia16_nemos  = fopen(configuracion.ficheronemos, "r")) != NULL)
    {
        sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' se ha abierto con éxito", configuracion.ficheronemos);
        Notificar(mensaje, NO_ERROR, ECO_NO);

        CargarArquitecturaIA16Nemonicos(f_ia16_nemos);

        /* cierro el fichero de nemónicos */
        if(fclose(f_ia16_nemos))
        {
            sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' no se ha podido cerrar", configuracion.ficheronemos);
            Notificar(mensaje, ERROR_SEGUIR, ECO_NO);
        }
    }
    else
    {
        sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' no se ha podido abrir", configuracion.ficheronemos);
        Notificar(mensaje, ERROR_SALIR, ECO_NO);
    }


    /* abro el fichero de ubicaciones de la arquitectura del repertorio */
    if((f_ia16_ubis  = fopen(configuracion.ficheroubis, "r")) != NULL)
    {
        sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' se ha abierto con éxito", configuracion.ficheroubis);
        Notificar(mensaje, NO_ERROR, ECO_NO);

        CargarArquitecturaIA16Simbolos(f_ia16_ubis);

        /* cierro el fichero de ubicaciones */
        if(fclose(f_ia16_ubis))
        {
            sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' no se ha podido cerrar", configuracion.ficheroubis);
            Notificar(mensaje, ERROR_SEGUIR, ECO_NO);
        }
    }
    else
    {
        sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' no se ha podido abrir", configuracion.ficheroubis);
        Notificar(mensaje, ERROR_SALIR, ECO_NO);
    }
}


void CargarProcesador()
{
    FILE *f_procesador;
    char mensaje[MAX_LINE];


    /* abro el fichero con la tabla de tiempos del procesador */
    if((f_procesador  = fopen(configuracion.ficherociclos, "r")) != NULL)
    {
        sprintf(mensaje, "[CargarProcesador] El fichero '%s' se ha abierto con éxito", configuracion.ficherociclos);
        Notificar(mensaje, NO_ERROR, ECO_NO);

        CargarTiemposProcesador(f_procesador);

        /* cierro el fichero del procesador */
        if(fclose(f_procesador))
        {
            sprintf(mensaje, "[CargarProcesador] El fichero '%s' no se ha podido cerrar", configuracion.ficherociclos);
            Notificar(mensaje, ERROR_SEGUIR, ECO_NO);
        }
    }
    else
    {
        sprintf(mensaje, "[CargarProcesador] El fichero '%s' no se ha podido abrir", configuracion.ficherociclos);
        Notificar(mensaje, ERROR_SALIR, ECO_NO);    
    }
}


/* carga de las bases de datos */

void CargarBasesDatos()
{
    CargarArquitecturaIA16();
    if(configuracion.cpi == SI) CargarProcesador();
}


/* libera memoria bases de datos */

void LiberarMemoriaBasesDatos()
{
    free(nemonicos);
    free(simbolos);
    if(configuracion.cpi == SI) free(ciclos);
}



#if 0

    /* la función strtok de <string.h> descompone la línea en campos */
    /* OJO: modifica la cadena de caracteres de la línea que se le pasa */
    
    /* capturo el primer campo */    
    campo = strtok(linea, "\t");
    while(campo != NULL)
    {
        /* trato el campo */
        
        /* capturo el siguiente campo */
        campo = strtok( NULL, seps );
        /* seps son los separadores, en este caso '\t' */
    }

    /* la función getopt del POSIX hace algo parecido */
#endif


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>