Annotation of ADD_ver_10/Source Code/Source Files/Auxiliares.c, revision 1.2

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

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