Annotation of ADD_ver_10/Auxiliares.c, revision 1.1
1.1 ! rico 1: /********************************************************************/
! 2: /* Auxiliares.c */
! 3: /* */
! 4: /* Copyright (c) 1997-2006 Rafael Rico (rafael.rico@uah.es) */
! 5: /* */
! 6: /* This file is part of ADD version 5.10. */
! 7: /* */
! 8: /* ADD is free software; you can redistribute it and/or modify */
! 9: /* it under the terms of the GNU General Public License as */
! 10: /* published by the Free Software Foundation; either version 2 of */
! 11: /* the License, or (at your option) any later version. */
! 12: /* */
! 13: /* ADD is distributed in the hope that it will be useful, */
! 14: /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
! 15: /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
! 16: /* GNU General Public License for more details. */
! 17: /* */
! 18: /* You should have received a copy of the GNU General Public */
! 19: /* License along with ADD; if not, write to the Free Software */
! 20: /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
! 21: /* 02111-1307 USA */
! 22: /* */
! 23: /* --------------------------- History --------------------------- */
! 24: /* */
! 25: /* Revision 1.2. 01/2006 */
! 26: /* Added GPL License and JavaDoc style documentation */
! 27: /* */
! 28: /* Revision 1.1. 09/2005 */
! 29: /* Initial Revision */
! 30: /* */
! 31: /********************************************************************/
! 32:
! 33:
! 34: /******************************************************************************/
! 35: /* MÓDULO: Auxiliares.c */
! 36: /* */
! 37: /* Este módulo contiene las funciones que crean ficheros. */
! 38: /******************************************************************************/
! 39: /* Fecha: 16 de septiembre de 2005 */
! 40: /******************************************************************************/
! 41:
! 42: #include <stdio.h>
! 43: #include <stdlib.h>
! 44: #include <string.h>
! 45: #include <ctype.h>
! 46:
! 47: #include "defines.h"
! 48: #include "tipos.h"
! 49: #include "auxiliares.h"
! 50:
! 51:
! 52: /* configuración */
! 53: extern struct argumentos configuracion;
! 54:
! 55: /* bases de datos */
! 56: extern unsigned int num_nemonicos;
! 57: extern operacion *nemonicos;
! 58: extern unsigned int num_simbolos;
! 59: extern operando *simbolos;
! 60: extern unsigned int num_tiempos;
! 61: extern tiempo *ciclos;
! 62:
! 63: extern unsigned int num_ubicaciones;
! 64: extern ubicacion *datos;
! 65:
! 66:
! 67:
! 68:
! 69: /* LISTAS Y BASES DE DATOS */
! 70:
! 71: /* funciones para manipular la base de datos */
! 72:
! 73: int BDBuscarCadena(int idtabla, int idcampo, char *cadena)
! 74: {
! 75: unsigned int i = 0; /* los registros de las bases de datos comienzan en el índice 0 */
! 76: int encontrado = NO;
! 77: char mensaje[MAX_LINE];
! 78:
! 79: switch (idtabla)
! 80: {
! 81: case TABLA_NEMONICOS:
! 82: switch (idcampo)
! 83: {
! 84: case CAMPO_NEMONICO:
! 85: while(i<num_nemonicos && encontrado == NO)
! 86: {
! 87: if (strcmp(nemonicos[i].nemonico, cadena)) i++; /* no encontrado */
! 88: else encontrado = SI; /* encontrado */
! 89: }
! 90: break;
! 91:
! 92: default:
! 93: /* emitir un error al fichero de log */
! 94: sprintf(mensaje, "[BDBuscarCadena] El campo no existe en la Tabla Nemónicos");
! 95: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 96: break;
! 97: }
! 98: break;
! 99:
! 100: case TABLA_SIMBOLOS:
! 101: switch (idcampo)
! 102: {
! 103: case CAMPO_SIMBOLO:
! 104: while(i<num_simbolos && encontrado == NO)
! 105: {
! 106: if (strcmp(simbolos[i].simbolo, cadena)) i++; /* no encontrado */
! 107: else encontrado = SI; /* encontrado */
! 108: }
! 109: break;
! 110:
! 111: default:
! 112: /* emitir un error al fichero de log */
! 113: sprintf(mensaje, "[BDBuscarCadena] El campo no existe en la Tabla Símbolos");
! 114: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 115: break;
! 116: }
! 117: break;
! 118:
! 119: case TABLA_CICLOS:
! 120: switch (idcampo)
! 121: {
! 122: case CAMPO_IDENTIFICADOR:
! 123: while(i<num_tiempos && encontrado == NO)
! 124: {
! 125: if (strcmp(ciclos[i].identificador, cadena)) i++; /* no encontrado */
! 126: else encontrado = SI; /* encontrado */
! 127: }
! 128: break;
! 129:
! 130: default:
! 131: /* emitir un error al fichero de log */
! 132: sprintf(mensaje, "[BDBuscarCadena] El campo no existe en la Tabla Ciclos");
! 133: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 134: break;
! 135: }
! 136: break;
! 137:
! 138: case TABLA_UBICACIONES:
! 139: switch (idcampo)
! 140: {
! 141: case CAMPO_NOMBRE:
! 142: while(i<num_ubicaciones && encontrado == NO)
! 143: {
! 144: if (strcmp(datos[i].nombre, cadena)) i++; /* no encontrado */
! 145: else encontrado = SI; /* encontrado */
! 146: }
! 147: break;
! 148:
! 149: default:
! 150: /* emitir un error al fichero de log */
! 151: sprintf(mensaje, "[BDBuscarCadena] El campo no existe en la Tabla Ubicaciones");
! 152: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 153: break;
! 154: }
! 155: break;
! 156:
! 157: default:
! 158: /* emitir un error al fichero de log */
! 159: sprintf(mensaje, "[BDBuscarCadena] La tabla especificada no existe");
! 160: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 161: break;
! 162: }
! 163: if(encontrado == NO) return(-1);
! 164: else return(i);
! 165: }
! 166:
! 167:
! 168: /* listas */
! 169: /* esta función añade un elemento a una lista */
! 170:
! 171: void AgregarElementoLista(char *lista, char *cadena)
! 172: {
! 173: if (lista[0] == '\0') strcpy (lista, cadena);
! 174: else {strcat (lista, ":"); strcat (lista, cadena);}
! 175: }
! 176:
! 177:
! 178:
! 179: /* esta función busca un elemento en una lista y devuelve el índice o 0 si no está */
! 180:
! 181: unsigned int BuscarElementoLista(char *lista, char *cadena)
! 182: {
! 183: char copialista[MAX_LISTA];
! 184: char *elemento; /* es un puntero a char para la función strtok */
! 185: unsigned int indice = 1;
! 186:
! 187: strcpy(copialista, lista);
! 188:
! 189: elemento = strtok(copialista, ":"); /* el separador de elementos de la lista es ':' */
! 190: while(elemento != NULL)
! 191: {
! 192: if(strcmp(elemento, cadena) == 0) return indice;
! 193: else indice++;
! 194:
! 195: /* capturo el siguiente campo */
! 196: elemento = strtok(NULL, ":");
! 197: }
! 198: return 0;
! 199: /* esta función se puede implementar también usando 'strstr' */
! 200: }
! 201:
! 202:
! 203:
! 204: /* esta función elimina un elemento de una lista */
! 205:
! 206: void EliminarElementoLista(char *lista, char *cadena)
! 207: {
! 208: char *puntero;
! 209: unsigned int indice1;
! 210: unsigned int indice2 = 1;
! 211:
! 212: puntero = lista;
! 213: indice1 = BuscarElementoLista(lista, cadena);
! 214:
! 215: if(indice1 == 0) return;
! 216:
! 217: while(indice2 != indice1)
! 218: {
! 219: if(*puntero == ':') indice2++;
! 220: puntero++;
! 221: }
! 222:
! 223: if(puntero != lista) /* el elemento no es el primero */
! 224: {
! 225: *(puntero - 1) = '\0'; /* corto la cadena en el separador antes del elemento */
! 226: if(*(puntero + strlen(cadena)) == ':') /* el elemento no es el último */
! 227: {
! 228: strcat(lista, (puntero + strlen(cadena)));
! 229: }
! 230: }
! 231: else strcpy(lista, (puntero + strlen(cadena) + 1));
! 232: }
! 233:
! 234:
! 235:
! 236: /* INICIALIZACIÓN DE DATOS */
! 237:
! 238: void IniciarTarjeta(fichainstruccion *tarjetaoperandos)
! 239: {
! 240: strcpy(tarjetaoperandos->nemonico, "");
! 241: strcpy(tarjetaoperandos->op1, "");
! 242: strcpy(tarjetaoperandos->op2, "");
! 243: strcpy(tarjetaoperandos->hexadecimal, "");
! 244: tarjetaoperandos->longitud = 0;
! 245: strcpy(tarjetaoperandos->prefijo, "");
! 246: tarjetaoperandos->salto = NO_SALTO;
! 247: tarjetaoperandos->ciclosALU = 0;
! 248: tarjetaoperandos->ciclosBIU = 0;
! 249: strcpy(tarjetaoperandos->leidoimpldatos, "");
! 250: strcpy(tarjetaoperandos->leidoimpldir, "");
! 251: strcpy(tarjetaoperandos->leidoimplpila, "");
! 252: strcpy(tarjetaoperandos->leidoimplestado, "");
! 253: strcpy(tarjetaoperandos->leidoexpldatos, "");
! 254: strcpy(tarjetaoperandos->leidoexpldir, "");
! 255: strcpy(tarjetaoperandos->leidoexplpila, "");
! 256: strcpy(tarjetaoperandos->leidoexplestado, "");
! 257: strcpy(tarjetaoperandos->escritoimpldatos, "");
! 258: strcpy(tarjetaoperandos->escritoimpldir, "");
! 259: strcpy(tarjetaoperandos->escritoimplpila, "");
! 260: strcpy(tarjetaoperandos->escritoimplestado, "");
! 261: strcpy(tarjetaoperandos->escritoexpldatos, "");
! 262: strcpy(tarjetaoperandos->escritoexpldir, "");
! 263: strcpy(tarjetaoperandos->escritoexplpila, "");
! 264: strcpy(tarjetaoperandos->escritoexplestado, "");
! 265: }
! 266:
! 267:
! 268:
! 269: /* HERRAMIENTAS */
! 270:
! 271: unsigned long TamanoFichero(char *fichero)
! 272: {
! 273: FILE *handle;
! 274: unsigned long tamano = 0;
! 275: char mensaje[MAX_LINE];
! 276:
! 277:
! 278: if((handle = fopen(fichero, "rb")) != NULL)
! 279: {
! 280: /*
! 281: sprintf(mensaje, "[TamañoFichero] El fichero '%s' se ha abierto con éxito", fichero);
! 282: Notificar(mensaje, NO_ERROR, ECO_NO);
! 283: */
! 284:
! 285: fseek(handle, 0L, SEEK_END);
! 286: tamano = ftell(handle);
! 287:
! 288: /* cierro el fichero */
! 289: if(fclose(handle))
! 290: {
! 291: sprintf(mensaje, "[TamañoFichero] El fichero '%s' no se ha podido cerrar", fichero);
! 292: Notificar(mensaje, ERROR_SEGUIR, ECO_NO);
! 293: }
! 294: }
! 295: else
! 296: {
! 297: sprintf(mensaje, "[TamañoFichero] El fichero '%s' no se ha podido abrir", fichero);
! 298: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 299: }
! 300:
! 301: return tamano;
! 302: }
! 303:
! 304:
! 305:
! 306: void DeterminarRango()
! 307: {
! 308: unsigned long total_instrucciones; /* total en la traza */
! 309: unsigned long cantidad; /* cantidad a analizar */
! 310: char mensaje[MAX_LINE];
! 311:
! 312: /* calculo la cantidad de instrucciones en la traza a partir del tamaño del fichero */
! 313: total_instrucciones = TamanoFichero(configuracion.ficherodatos)/BYTES_POR_INSTRUCCION;
! 314:
! 315: /*
! 316: printf("Total instrucciones en '%s' = %lu\n", configuracion.ficherodatos, total_instrucciones);
! 317: _getch();
! 318: */
! 319:
! 320: if(configuracion.ultima == 0) /* significa que manda el rango */
! 321: {
! 322: cantidad = (unsigned long)(configuracion.rango * total_instrucciones)/100.00;
! 323:
! 324: if(configuracion.primera == 0) /* significa que manda el porcentaje de comienzo */
! 325: configuracion.primera = (unsigned long) 1 + (configuracion.comienzo * total_instrucciones)/100.00;
! 326: /* la cuenta de instrucciones comienza en '1' */
! 327:
! 328: else if(configuracion.primera > total_instrucciones)
! 329: {
! 330: sprintf(mensaje, "[DeterminarRango] La primera instrucción está fuera del fichero de datos");
! 331: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 332: }
! 333: configuracion.ultima = configuracion.primera + cantidad;
! 334: if(configuracion.ultima > total_instrucciones) configuracion.ultima = total_instrucciones;
! 335: }
! 336:
! 337: cantidad = configuracion.ultima - configuracion.primera + 1;
! 338:
! 339: if(cantidad < configuracion.ventana)
! 340: {
! 341: sprintf(mensaje, "[DeterminarRango] El rango de análisis es demasiado pequeño");
! 342: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 343: }
! 344: }
! 345:
! 346:
! 347:
! 348:
! 349: /* ARITMÉTICAS */
! 350:
! 351: /* esta función calcula el nuevo valor promedio de una serie de datos */
! 352: /* a partir del valor anterior y del valor en curso (actual) */
! 353:
! 354: double CalcularNuevoPromedio (double promedioanterior, double valoractual, unsigned long n)
! 355: {
! 356: double nuevopromedio;
! 357:
! 358: nuevopromedio = ((n - 1) * promedioanterior + valoractual) / n;
! 359:
! 360: return nuevopromedio;
! 361: }
! 362:
! 363:
! 364: /* esta función calcula el inverso normalizado y previene la división por 0 */
! 365:
! 366: double InversoNormalizado (unsigned int dimension, double valor)
! 367: {
! 368: double inverso;
! 369: char mensaje[MAX_LINE];
! 370:
! 371: if(valor == 0.0)
! 372: {
! 373: sprintf(mensaje, "[InversoNormalizado] El valor del denominador es nulo");
! 374: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 375: }
! 376:
! 377: if(dimension == 0)
! 378: {
! 379: sprintf(mensaje, "[InversoNormalizado] La dimensión de la normalización es nula");
! 380: Notificar(mensaje, ERROR_SEGUIR, ECO_NO);
! 381: }
! 382:
! 383: inverso = dimension / valor;
! 384:
! 385: return inverso;
! 386: }
! 387:
! 388:
! 389:
! 390: /* FORMATO */
! 391:
! 392: /* esta función genera la cadena en lenguaje ensamblador de una instrucción */
! 393: /* a partir del prefijo, nemónico y operandos */
! 394: /* según un tipo de notación especificado (INTEL, ATT) */
! 395:
! 396: void CadenaEnsamblador(char *prefijo, char *nemonico, char *operando1, char *operando2, unsigned char notacion, char *cadena)
! 397: {
! 398: char auxiliar[2*MAX_NEMO + 2*MAX_OPE];
! 399:
! 400: switch(notacion)
! 401: {
! 402: case 0: /* notación de INTEL */
! 403:
! 404: sprintf(cadena, "%s%s", prefijo, prefijo[0]!='\0' ? " ":"");
! 405:
! 406: sprintf(auxiliar, "%s", nemonico);
! 407: strcat(cadena, auxiliar);
! 408:
! 409: sprintf(auxiliar, "%s%s", operando1[0]!='\0' ? " ":"", operando1);
! 410: strcat(cadena, auxiliar);
! 411:
! 412: sprintf(auxiliar, "%s%s%s", (operando1[0]!='\0' && operando2[0]!='\0') ? ",":"", operando2[0]!='\0' ? " ":"", operando2);
! 413: strcat(cadena, auxiliar);
! 414:
! 415: /* más elegante usar el índice que devuelve sprintf y sumarlo al puntero cadena */
! 416: /* sprintf(cadena + i, ""... */
! 417: break;
! 418:
! 419: case 1: /* notación ATT */
! 420: break;
! 421: }
! 422: }
! 423:
! 424:
! 425: /* esta función convierte una cadena hexadecimal a una secuencia de bytes */
! 426:
! 427: void ConvertirHex2Bin(char *cadenahex, unsigned char *secuencia, unsigned char maxformato)
! 428: {
! 429: int i;
! 430: char bytehex[3];
! 431: char mensaje[MAX_LINE];
! 432:
! 433: /* control de errores */
! 434: if(strlen(cadenahex)==0)
! 435: {
! 436: sprintf(mensaje, "[ConvertirHex2Bin] La cadena hexadecimal está vacía");
! 437: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 438: }
! 439: else if(strlen(cadenahex)%2!=0)
! 440: {
! 441: sprintf(mensaje, "[ConvertirHex2Bin] La cadena hexadecimal '%s' no contiene un número entero de bytes", cadenahex);
! 442: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 443: }
! 444:
! 445: /* relleno la secuencia de 2 instrucciones en binario con 0s */
! 446: /* (2 instrucciones de tamaño máximo 'maxformato') */
! 447: for(i=0; i<2*maxformato; i++) *(secuencia+i) = 0;
! 448:
! 449: do
! 450: {
! 451: for(i=0; i<2; i++)
! 452: {
! 453: bytehex[i]=*(cadenahex+i);
! 454: if(isxdigit(bytehex[i])==0) /* error -> dígito no hexadecimal */
! 455: {
! 456: sprintf(mensaje, "[ConvertirHex2Bin] El byte '%s' contiene un dígito no hexadecimal", cadenahex);
! 457: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 458: }
! 459: }
! 460: bytehex[3]='\0';
! 461: sscanf(bytehex, "%2X", secuencia);
! 462: secuencia++;
! 463: }
! 464: while(*(cadenahex+=2)!='\0');
! 465: }
! 466:
! 467: /* NOTA: otra posibilidad para esta función consiste en copiar la cadena hexadecimal */
! 468: /* en un array y recorrer con un puntero dicha cadena desde el final de 2 en 2 caracteres */
! 469: /* antes de decrementar el puntero se corta el array con un \0 para "ver" 2 dígitos */
! 470: /* hexadecimales cada vez; este método consume memoria para el array y para el puntero */
! 471: /* si no copio la cadena hexadecimal la pierdo al trocearla con \0 */
! 472:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>