/********************************************************************/
/* BasesDatos.c */
/* */
/* Copyright (c) 1997-2006 Rafael Rico (rafael.rico@uah.es) */
/* */
/* This file is part of ADD version 5.10. */
/* */
/* ADD is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as */
/* published by the Free Software Foundation; either version 2 of */
/* the License, or (at your option) any later version. */
/* */
/* ADD is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public */
/* License along with ADD; if not, write to the Free Software */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
/* 02111-1307 USA */
/* */
/* --------------------------- History --------------------------- */
/* */
/* Revision 1.2. 01/2006 */
/* Added GPL License and JavaDoc style documentation */
/* */
/* Revision 1.1. 09/2005 */
/* Initial Revision */
/* */
/********************************************************************/
/******************************************************************************/
/* 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>