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>