/********************************************************************/
/* 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>