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

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