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

1.2     ! rico        1: /********************************************************************/
        !             2: /*  BasesDatos.c                                                    */
        !             3: /*                                                                  */
        !             4: /*                                                                  */
        !             5: /*  Copyright (c) 1997-2006 Rafael Rico      (rafael.rico@uah.es)   */
        !             6: /*                                                                  */
        !             7: /*  Este fichero forma parte de ADD                                 */
        !             8: /*  (Analizador de Dependencias de Datos)                           */
        !             9: /*  Version 5.10.                                                   */
        !            10: /*                                                                  */
        !            11: /*                                                                  */
        !            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.                               */
        !            17: /*                                                                  */
        !            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.                                                   */
        !            23: /*                                                                  */
        !            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.                                   */
        !            28: /*                                                                  */
        !            29: /*  -------------------------- Historia --------------------------- */
        !            30: /*                                                                  */
        !            31: /*  $Id$                                                            */
        !            32: /*                                                                  */
        !            33: /*  Revisión 1.2. 01/2006                                           */
        !            34: /*  Se añade la licencia GPL y documentación en estilo Javadoc      */
        !            35: /*                                                                  */
        !            36: /*  Revisión 1.1. 09/2005                                           */
        !            37: /*  Versión inicial                                                 */
        !            38: /*                                                                  */
        !            39: /********************************************************************/
        !            40: 
1.1       rico       41: /******************************************************************************/
                     42: /* MÓDULO: BasesDatos.c                                                       */
                     43: /*                                                                            */
                     44: /* Este módulo carga en memoria la base de datos que modela la arquitectura   */
                     45: /* del repertorio IA16 (tabla de nemónicos y tabla de ubicaciones de datos)   */
                     46: /* y la tabla de tiempos de un procesador en ciclos (tiempo de ejecución de   */
                     47: /* operaciones, tiempo de acceso a operandos y tiempo de cómputo de           */
                     48: /* direcciones de memoria.                                                    */
                     49: /******************************************************************************/
                     50: /* Fecha: 19 de septiembre de 2005                                            */
                     51: /******************************************************************************/
                     52: 
                     53: #include <stdio.h>
                     54: #include <stdlib.h>
                     55: #include <string.h>
                     56: 
                     57: #include "defines.h"
                     58: #include "tipos.h"
                     59: #include "basesdatos.h"
                     60: 
                     61: 
                     62: /* configuración */
                     63: extern struct argumentos configuracion;
                     64: 
                     65: /* bases de datos */
                     66: extern unsigned int num_nemonicos;
                     67: extern operacion *nemonicos;
                     68: extern unsigned int num_simbolos;
                     69: extern operando *simbolos;
                     70: extern unsigned int num_tiempos;
                     71: extern tiempo *ciclos;
                     72: 
                     73: 
                     74: void CargarArquitecturaIA16Nemonicos(FILE *f_ia16_nemos)
                     75: {
                     76:     unsigned int i;
                     77:     char linea[MAX_LINE];
                     78:     char *registro, *campo;
                     79:     char mensaje[MAX_LINE];
                     80: 
                     81: 
                     82:     sprintf(mensaje, "[CargarArquitecturaIA16Nemonicos] Cargando base de datos del repertorio IA16...");
                     83:     Notificar(mensaje, NO_ERROR, ECO_NO);
                     84: 
                     85:     /* salto los comentarios */
                     86:     do fgets (linea, MAX_LINE, f_ia16_nemos); while (linea[0]=='#');
                     87: 
                     88:     /* leo el número de registros (primera línea con información) */
                     89:     num_nemonicos = atoi(linea);
                     90: 
                     91:     sprintf(mensaje, "[CargarArquitecturaIA16Nemonicos] Reservo memoria para %d registros", num_nemonicos);
                     92:     Notificar(mensaje, NO_ERROR, ECO_NO);
                     93: 
                     94:     /* malloc reserva memoria; calloc reserva memoria y rellena con 0's */
                     95:     /* calloc es más lenta pero me asegura que los valores numéricos van */
                     96:     /* a ser 0 y las cadenas van a ser vacías */
                     97:     nemonicos = calloc(num_nemonicos, sizeof(operacion));
                     98:     if (nemonicos == NULL)
                     99:     {
                    100:         sprintf(mensaje, "[CargarArquitecturaIA16Nemonicos] Memoria insuficiente");
                    101:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    102:         /* el programa finaliza si no hay memoria suficiente */
                    103:     }
                    104: 
                    105:     sprintf(mensaje, "[CargarArquitecturaIA16Nemonicos] Cargando datos de nemónicos...");
                    106:     Notificar(mensaje, NO_ERROR, ECO_NO);
                    107: 
                    108:     i = 0;
                    109:     while(i<num_nemonicos)
                    110:     {
                    111:         /* salto los comentarios */
                    112:         do fgets (linea, MAX_LINE, f_ia16_nemos); while(linea[0]=='#');
                    113: 
                    114:         /* hago un barrido de la línea hasta encontrar el final de línea */
                    115:         /* cada ocurrencia de '\t' la cambio por '\0' para convertirlo   */
                    116:         /* en una cadena separada (campo)                                */
                    117: 
                    118:         /* el puntero 'registro' me permite moverme por la línea */
                    119:         /* el puntero 'campo' se encarga se señalar el comienzo de los campos */
                    120:         registro = linea;
                    121:         campo = linea;
                    122:         while(*++registro!='\0')
                    123:         {
                    124:             if(*registro=='\t')
                    125:             {
                    126:                 *registro = '\0';    /* finalizo un campo */
                    127:                 /* campo nemonico */
                    128:                 if(campo[0]!='-') strcpy(nemonicos[i].nemonico, campo);
                    129:                 else
                    130:                 {
                    131:                     switch(campo[1])
                    132:                     {
                    133:                         case 't':    /* tipo de nemonico */
                    134:                         nemonicos[i].tipo = atoi(campo+3);
                    135:                         break;
                    136: 
                    137:                         case '1':    /* modo del operando 1 (destino) explícito */
                    138:                         nemonicos[i].modo_op1 = atoi(campo+3);
                    139:                         break;
                    140: 
                    141:                         case '2':    /* modo del operando 2 (fuente) explícito */
                    142:                         nemonicos[i].modo_op2 = atoi(campo+3);
                    143:                         break;
                    144: 
                    145:                         case 'e':   /* implícitos escritos */
                    146:                         strcpy(nemonicos[i].implicitos_escritos, campo+3);
                    147:                         break;
                    148: 
                    149:                         case 'l':   /* implícitos leidos */
                    150:                         strcpy(nemonicos[i].implicitos_leidos, campo+3);
                    151:                         break;
                    152: 
                    153:                         default:
                    154:                         /* mandar un error a un fichero de log */
                    155:                         break;
                    156:                     }
                    157:                 }
                    158:                 campo = registro+1;    /* hago que apunte al siguiente */
                    159:             }
                    160:         }
                    161: 
                    162:         /* echo */
                    163:         /* printf("%3d %10s %d %d\t%15s\t%30s\n", i, operaciones[i].nemonico, 
                    164:                      operaciones[i].modo_fuente, operaciones[i].modo_destino, 
                    165:                      operaciones[i].implicitos_leidos, 
                    166:                      operaciones[i].implicitos_escritos); */
                    167:         /* _getch(); */
                    168: 
                    169:         i++;    /* índice del siguiente registro */
                    170:     }
                    171: 
                    172:     sprintf(mensaje, "[CargarArquitecturaIA16Nemonicos] La tabla de nemónicos se ha cargado con éxito");
                    173:     Notificar(mensaje, NO_ERROR, ECO_NO);
                    174: }
                    175: 
                    176: 
                    177: void CargarArquitecturaIA16Simbolos(FILE *f_ia16_ubis)
                    178: {
                    179:     unsigned int i;
                    180:     char linea[MAX_LINE];
                    181:     char *campo;
                    182:     char mensaje[MAX_LINE];
                    183: 
                    184:     sprintf(mensaje, "[CargarArquitecturaIA16Simbolos] Cargando base de datos del repertorio IA16...");
                    185:     Notificar(mensaje, NO_ERROR, ECO_NO);
                    186: 
                    187:     /* salto los comentarios */
                    188:     do fgets (linea, MAX_LINE, f_ia16_ubis); while (linea[0]=='#');
                    189: 
                    190:     /* leo el número de registros (primera línea con información) */
                    191:     num_simbolos = atoi(linea);
                    192: 
                    193:     sprintf(mensaje, "[CargarArquitecturaIA16Simbolos] Reservo memoria para %d registros", num_simbolos);
                    194:     Notificar(mensaje, NO_ERROR, ECO_NO);
                    195: 
                    196:     /* malloc reserva memoria; calloc reserva memoria y rellena con 0's */
                    197:     /* calloc es más lenta pero me asegura que los valores numéricos van */
                    198:     /* a ser 0 y las cadenas van a ser vacías */
                    199:     simbolos = calloc(num_simbolos, sizeof(operando));
                    200:     if (simbolos == NULL)
                    201:     {
                    202:         sprintf(mensaje, "[CargarArquitecturaIA16Simbolos] Memoria insuficiente");
                    203:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    204:         /* el programa finaliza si no hay memoria suficiente */
                    205:     }
                    206: 
                    207:     sprintf(mensaje, "[CargarArquitecturaIA16Simbolos] Cargando datos de símbolos...");
                    208:     Notificar(mensaje, NO_ERROR, ECO_NO);
                    209: 
                    210:     i = 0;
                    211:     while(i<num_simbolos)
                    212:     {
                    213:         /* salto los comentarios */
                    214:         do fgets (linea, MAX_LINE, f_ia16_ubis); while(linea[0]=='#');
                    215: 
                    216:         campo = strtok(linea, "\t\n");    /* el separador de campos es '\t' */
                    217:                                           /* añado '\n' porque al final de linea */
                    218:                                           /* tengo ese caracter y lo toma por un campo */
                    219:         while(campo != NULL)
                    220:         {
                    221:             /* trato el campo capturado por la función strtok */
                    222:             /* campo símbolo */
                    223:             if(campo[0]!='-') strcpy(simbolos[i].simbolo, campo);
                    224:             else
                    225:             {
                    226:                 switch(campo[1])
                    227:                 {
                    228:                     case 'd':    /* dependencias */
                    229:                     strcpy(simbolos[i].dependencias, campo+3);
                    230:                     break;
                    231: 
                    232:                     case 's':    /* segmento por defecto */
                    233:                     simbolos[i].segmento = atoi (campo+3);
                    234:                     break;
                    235: 
                    236:                     case 't':    /* tipo de ubicación */
                    237:                     simbolos[i].tipo = atoi (campo+3);
                    238:                     break;
                    239: 
                    240:                     default:
                    241:                     /* mandar un error a un fichero de log */
                    242:                     break;
                    243:                 }
                    244:             }
                    245:             /* capturo el siguiente campo */
                    246:             campo = strtok(NULL, "\t\n");
                    247:         }
                    248:         
                    249:         /* echo */
                    250:         /* printf(); */
                    251:         /* _getch(); */
                    252: 
                    253:         i++;    /* índice del siguiente registro */
                    254:     }
                    255: 
                    256:     sprintf(mensaje, "[CargarArquitecturaIA16Simbolos] La tabla de símbolos se ha cargado con éxito");
                    257:     Notificar(mensaje, NO_ERROR, ECO_NO);
                    258: }
                    259: 
                    260: 
                    261: void CargarTiemposProcesador(FILE *f_procesador)
                    262: {
                    263:     unsigned int i;
                    264:     char linea[MAX_LINE];
                    265:     char *campo;
                    266:     char mensaje[MAX_LINE];
                    267: 
                    268:     sprintf(mensaje, "[CargarTiemposProcesador] Cargando base de datos del procesador...");
                    269:     Notificar(mensaje, NO_ERROR, ECO_NO);
                    270: 
                    271:     /* salto los comentarios */
                    272:     do fgets (linea, MAX_LINE, f_procesador); while (linea[0]=='#');
                    273: 
                    274:     /* leo el número de registros (primera línea con información) */
                    275:     num_tiempos = atoi(linea);
                    276: 
                    277:     sprintf(mensaje, "[CargarTiemposProcesador] Reservo memoria para %d registros", num_tiempos);
                    278:     Notificar(mensaje, NO_ERROR, ECO_NO);
                    279: 
                    280:     /* malloc reserva memoria; calloc reserva memoria y rellena con 0's */
                    281:     /* calloc es más lenta pero me asegura que los valores numéricos van */
                    282:     /* a ser 0 y las cadenas van a ser vacías */
                    283:     ciclos = calloc(num_tiempos, sizeof(tiempo));
                    284:     if (ciclos == NULL)
                    285:     {
                    286:         sprintf(mensaje, "[CargarTiemposProcesador] Memoria insuficiente");
                    287:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    288:         /* el programa finaliza si no hay memoria suficiente */
                    289:     }
                    290: 
                    291:     sprintf(mensaje, "[CargarTiemposProcesador] Cargando datos de tiempos...");
                    292:     Notificar(mensaje, NO_ERROR, ECO_NO);
                    293: 
                    294:     i = 0;
                    295:     while(i<num_tiempos)
                    296:     {
                    297:         /* salto los comentarios */
                    298:         do fgets (linea, MAX_LINE, f_procesador); while(linea[0]=='#');
                    299: 
                    300:         campo = strtok(linea, "\t\n");    /* el separador de campos es '\t' */
                    301:                                           /* añado '\n' porque al final de linea */
                    302:                                           /* tengo ese caracter y lo toma por un campo */
                    303:         while(campo != NULL)
                    304:         {
                    305:             /* trato el campo capturado por la función strtok */
                    306:             /* campo identificador */
                    307:             if(campo[0]!='-') strcpy(ciclos[i].identificador, campo);
                    308:             else
                    309:             {
                    310:                 switch(campo[1])
                    311:                 {
                    312:                     case 'c':    /* dependencias */
                    313:                     ciclos[i].ciclos = atoi (campo+3);
                    314:                     break;
                    315: 
                    316:                     default:
                    317:                     /* mandar un error a un fichero de log */
                    318:                     break;
                    319:                 }
                    320:             }
                    321:             /* capturo el siguiente campo */
                    322:             campo = strtok(NULL, "\t\n");
                    323:         }
                    324: 
                    325:         /* echo */
                    326:         /* printf(); */
                    327:         /* _getch(); */
                    328:         
                    329:         i++;    /* índice del siguiente registro */
                    330:     }
                    331: 
                    332:     sprintf(mensaje, "[CargarTiemposProcesador] La tabla de tiempos se ha cargado con éxito");
                    333:     Notificar(mensaje, NO_ERROR, ECO_NO);
                    334: }
                    335: 
                    336: 
                    337: void CargarArquitecturaIA16()
                    338: {
                    339:     FILE *f_ia16_nemos, *f_ia16_ubis;
                    340:     char mensaje[MAX_LINE];
                    341: 
                    342:     
                    343:     /* abro el fichero de nemónicos de la arquitectura del repertorio */
                    344:     if((f_ia16_nemos  = fopen(configuracion.ficheronemos, "r")) != NULL)
                    345:     {
                    346:         sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' se ha abierto con éxito", configuracion.ficheronemos);
                    347:         Notificar(mensaje, NO_ERROR, ECO_NO);
                    348: 
                    349:         CargarArquitecturaIA16Nemonicos(f_ia16_nemos);
                    350: 
                    351:         /* cierro el fichero de nemónicos */
                    352:         if(fclose(f_ia16_nemos))
                    353:         {
                    354:             sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' no se ha podido cerrar", configuracion.ficheronemos);
                    355:             Notificar(mensaje, ERROR_SEGUIR, ECO_NO);
                    356:         }
                    357:     }
                    358:     else
                    359:     {
                    360:         sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' no se ha podido abrir", configuracion.ficheronemos);
                    361:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    362:     }
                    363: 
                    364: 
                    365:     /* abro el fichero de ubicaciones de la arquitectura del repertorio */
                    366:     if((f_ia16_ubis  = fopen(configuracion.ficheroubis, "r")) != NULL)
                    367:     {
                    368:         sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' se ha abierto con éxito", configuracion.ficheroubis);
                    369:         Notificar(mensaje, NO_ERROR, ECO_NO);
                    370: 
                    371:         CargarArquitecturaIA16Simbolos(f_ia16_ubis);
                    372: 
                    373:         /* cierro el fichero de ubicaciones */
                    374:         if(fclose(f_ia16_ubis))
                    375:         {
                    376:             sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' no se ha podido cerrar", configuracion.ficheroubis);
                    377:             Notificar(mensaje, ERROR_SEGUIR, ECO_NO);
                    378:         }
                    379:     }
                    380:     else
                    381:     {
                    382:         sprintf(mensaje, "[CargarArquitecturaIA16] El fichero '%s' no se ha podido abrir", configuracion.ficheroubis);
                    383:         Notificar(mensaje, ERROR_SALIR, ECO_NO);
                    384:     }
                    385: }
                    386: 
                    387: 
                    388: void CargarProcesador()
                    389: {
                    390:     FILE *f_procesador;
                    391:     char mensaje[MAX_LINE];
                    392: 
                    393: 
                    394:     /* abro el fichero con la tabla de tiempos del procesador */
                    395:     if((f_procesador  = fopen(configuracion.ficherociclos, "r")) != NULL)
                    396:     {
                    397:         sprintf(mensaje, "[CargarProcesador] El fichero '%s' se ha abierto con éxito", configuracion.ficherociclos);
                    398:         Notificar(mensaje, NO_ERROR, ECO_NO);
                    399: 
                    400:         CargarTiemposProcesador(f_procesador);
                    401: 
                    402:         /* cierro el fichero del procesador */
                    403:         if(fclose(f_procesador))
                    404:         {
                    405:             sprintf(mensaje, "[CargarProcesador] El fichero '%s' no se ha podido cerrar", configuracion.ficherociclos);
                    406:             Notificar(mensaje, ERROR_SEGUIR, ECO_NO);
                    407:         }
                    408:     }
                    409:     else
                    410:     {
                    411:         sprintf(mensaje, "[CargarProcesador] El fichero '%s' no se ha podido abrir", configuracion.ficherociclos);
                    412:         Notificar(mensaje, ERROR_SALIR, ECO_NO);    
                    413:     }
                    414: }
                    415: 
                    416: 
                    417: /* carga de las bases de datos */
                    418: 
                    419: void CargarBasesDatos()
                    420: {
                    421:     CargarArquitecturaIA16();
                    422:     if(configuracion.cpi == SI) CargarProcesador();
                    423: }
                    424: 
                    425: 
                    426: /* libera memoria bases de datos */
                    427: 
                    428: void LiberarMemoriaBasesDatos()
                    429: {
                    430:     free(nemonicos);
                    431:     free(simbolos);
                    432:     if(configuracion.cpi == SI) free(ciclos);
                    433: }
                    434: 
                    435: 
                    436: 
                    437: #if 0
                    438: 
                    439:     /* la función strtok de <string.h> descompone la línea en campos */
                    440:     /* OJO: modifica la cadena de caracteres de la línea que se le pasa */
                    441:     
                    442:     /* capturo el primer campo */    
                    443:     campo = strtok(linea, "\t");
                    444:     while(campo != NULL)
                    445:     {
                    446:         /* trato el campo */
                    447:         
                    448:         /* capturo el siguiente campo */
                    449:         campo = strtok( NULL, seps );
                    450:         /* seps son los separadores, en este caso '\t' */
                    451:     }
                    452: 
                    453:     /* la función getopt del POSIX hace algo parecido */
                    454: #endif
                    455: 

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