Annotation of rpl/src/gestion_pile.c, revision 1.1
1.1 ! bertrand 1: /*
! 2: ================================================================================
! 3: RPL/2 (R) version 4.0.9
! 4: Copyright (C) 1989-2010 Dr. BERTRAND Joël
! 5:
! 6: This file is part of RPL/2.
! 7:
! 8: RPL/2 is free software; you can redistribute it and/or modify it
! 9: under the terms of the CeCILL V2 License as published by the french
! 10: CEA, CNRS and INRIA.
! 11:
! 12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
! 13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
! 14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
! 15: for more details.
! 16:
! 17: You should have received a copy of the CeCILL License
! 18: along with RPL/2. If not, write to info@cecill.info.
! 19: ================================================================================
! 20: */
! 21:
! 22:
! 23: #include "rpl.conv.h"
! 24:
! 25:
! 26: /*
! 27: ================================================================================
! 28: Procédure d'estimation de la longueur du tampon
! 29: ================================================================================
! 30: Entrée :
! 31: --------------------------------------------------------------------------------
! 32: Sortie :
! 33: --------------------------------------------------------------------------------
! 34: Effets de bord : néant
! 35: ================================================================================
! 36: */
! 37:
! 38: static inline void
! 39: estimation_taille_pile(struct_processus *s_etat_processus)
! 40: {
! 41: /*
! 42: * Cette fonction permet d'estimer un volant de structures de maillons
! 43: * de liste chaînée pour le programme courant et évite un certain nombre
! 44: * d'allocations de mémoire lors des manipulations de la pile. Cette taille
! 45: * est estimée au travers d'une chaîne de Markov.
! 46: */
! 47:
! 48: (*s_etat_processus).estimation_taille_pile_tampon =
! 49: ((*s_etat_processus).estimation_taille_pile_tampon *
! 50: ((double) 0.9)) + ((*s_etat_processus)
! 51: .hauteur_pile_operationnelle * ((double) 0.1));
! 52: return;
! 53: }
! 54:
! 55:
! 56: /*
! 57: ================================================================================
! 58: Procédure d'empilement d'un nouvel élément
! 59: ================================================================================
! 60: Entrée :
! 61: --------------------------------------------------------------------------------
! 62: Sortie :
! 63: --------------------------------------------------------------------------------
! 64: Effets de bord : néant
! 65: ================================================================================
! 66: */
! 67:
! 68: logical1
! 69: empilement(struct_processus *s_etat_processus,
! 70: struct_liste_chainee **l_base_pile, struct_objet *s_objet)
! 71: {
! 72: struct_liste_chainee *l_ancienne_base_liste;
! 73: struct_liste_chainee *l_nouvelle_base_liste;
! 74:
! 75: logical1 erreur;
! 76:
! 77: l_ancienne_base_liste = *l_base_pile;
! 78:
! 79: if ((*s_etat_processus).pile_tampon == NULL)
! 80: {
! 81: // Tampon vide, on alloue un élément.
! 82:
! 83: if ((l_nouvelle_base_liste = malloc(sizeof(struct_liste_chainee)))
! 84: == NULL)
! 85: {
! 86: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 87: return(d_erreur);
! 88: }
! 89: }
! 90: else
! 91: {
! 92: // Tampon utilisable, on retire un élément du tampon.
! 93:
! 94: l_nouvelle_base_liste = (*s_etat_processus).pile_tampon;
! 95: (*s_etat_processus).pile_tampon = (*l_nouvelle_base_liste).suivant;
! 96: (*s_etat_processus).taille_pile_tampon--;
! 97: }
! 98:
! 99: *l_base_pile = l_nouvelle_base_liste;
! 100: (**l_base_pile).donnee = s_objet;
! 101: (**l_base_pile).suivant = l_ancienne_base_liste;
! 102:
! 103: erreur = d_absence_erreur;
! 104:
! 105: /*
! 106: -- Ne considère que la pile opérationnelle -------------------------------------
! 107: */
! 108:
! 109: if ((*s_etat_processus).l_base_pile == *l_base_pile)
! 110: {
! 111: (*s_etat_processus).hauteur_pile_operationnelle++;
! 112: estimation_taille_pile(s_etat_processus);
! 113:
! 114: if ((*s_etat_processus).debug == d_vrai)
! 115: if (((*s_etat_processus).type_debug &
! 116: d_debug_pile_utilisateur) != 0)
! 117: {
! 118: if ((*s_etat_processus).langue == 'F')
! 119: {
! 120: printf("[%d] Empilement de type %d "
! 121: "(profondeur %lu)\n", (int) getpid(),
! 122: (*s_objet).type,
! 123: (*s_etat_processus).hauteur_pile_operationnelle);
! 124: }
! 125: else
! 126: {
! 127: printf("[%d] Pushing a type %d object "
! 128: "(depth %lu)\n", (int) getpid(), (*s_objet).type,
! 129: (*s_etat_processus).hauteur_pile_operationnelle);
! 130: }
! 131:
! 132: fflush(stdout);
! 133: }
! 134: }
! 135:
! 136: return erreur;
! 137: }
! 138:
! 139:
! 140: /*
! 141: ================================================================================
! 142: Procédure de dépilement d'un élément. L'emplacement est libéré dans la pile.
! 143: ================================================================================
! 144: Entrée :
! 145: --------------------------------------------------------------------------------
! 146: Sortie :
! 147: --------------------------------------------------------------------------------
! 148: Effets de bord : néant
! 149: ================================================================================
! 150: */
! 151:
! 152: logical1
! 153: depilement(struct_processus *s_etat_processus,
! 154: struct_liste_chainee **l_base_pile, struct_objet **s_objet)
! 155: {
! 156: struct_liste_chainee *l_ancienne_base_liste;
! 157: struct_liste_chainee *l_nouvelle_base_liste;
! 158:
! 159: logical1 erreur;
! 160:
! 161: if (*l_base_pile == NULL)
! 162: {
! 163: (*s_etat_processus).erreur_execution = d_ex_pile_vide;
! 164: erreur = d_erreur;
! 165: }
! 166: else
! 167: {
! 168:
! 169: /*
! 170: -- Ne considère que la pile opérationnelle -------------------------------------
! 171: */
! 172:
! 173: l_ancienne_base_liste = *l_base_pile;
! 174: *s_objet = (*l_ancienne_base_liste).donnee;
! 175:
! 176: if ((*s_etat_processus).l_base_pile == *l_base_pile)
! 177: {
! 178: if ((*s_etat_processus).debug == d_vrai)
! 179: if (((*s_etat_processus).type_debug &
! 180: d_debug_pile_utilisateur) != 0)
! 181: {
! 182: if ((*s_etat_processus).langue == 'F')
! 183: {
! 184: printf("[%d] Dépilement de type %d "
! 185: "(profondeur %lu)\n", (int) getpid(),
! 186: (*(*s_objet)).type,
! 187: (*s_etat_processus).hauteur_pile_operationnelle);
! 188: }
! 189: else
! 190: {
! 191: printf("[%d] Pulling a type %d object "
! 192: "(depth %lu)\n", (int) getpid(), (*(*s_objet)).type,
! 193: (*s_etat_processus).hauteur_pile_operationnelle);
! 194: }
! 195:
! 196: fflush(stdout);
! 197: }
! 198:
! 199: (*s_etat_processus).hauteur_pile_operationnelle--;
! 200: estimation_taille_pile(s_etat_processus);
! 201: }
! 202:
! 203: l_nouvelle_base_liste = (*l_ancienne_base_liste).suivant;
! 204:
! 205: *l_base_pile = l_nouvelle_base_liste;
! 206: erreur = d_absence_erreur;
! 207:
! 208: if ((*s_etat_processus).taille_pile_tampon <= (10 * ((*s_etat_processus)
! 209: .estimation_taille_pile_tampon + 1)))
! 210: {
! 211: // Enregistrement de la structure pour usage ultérieur.
! 212:
! 213: (*l_ancienne_base_liste).donnee = NULL;
! 214: (*l_ancienne_base_liste).suivant = (*s_etat_processus).pile_tampon;
! 215: (*s_etat_processus).pile_tampon = l_ancienne_base_liste;
! 216: (*s_etat_processus).taille_pile_tampon++;
! 217: }
! 218: else
! 219: {
! 220: // Libération car le tampon est plein.
! 221:
! 222: free(l_ancienne_base_liste);
! 223: }
! 224: }
! 225:
! 226: return erreur;
! 227: }
! 228:
! 229:
! 230: /*
! 231: ================================================================================
! 232: Procédures affichant la pile opérationnelle
! 233: ================================================================================
! 234: Entrée :
! 235: --------------------------------------------------------------------------------
! 236: Sortie :
! 237: --------------------------------------------------------------------------------
! 238: Effets de bord : néant
! 239: ================================================================================
! 240: */
! 241:
! 242: void
! 243: affichage_pile(struct_processus *s_etat_processus, struct_liste_chainee
! 244: *l_element_courant, unsigned long niveau_courant)
! 245: {
! 246: ecriture_pile(s_etat_processus, stdout, l_element_courant, niveau_courant);
! 247: return;
! 248: }
! 249:
! 250: void
! 251: ecriture_pile(struct_processus *s_etat_processus, file *flux,
! 252: struct_liste_chainee *l_element_courant, unsigned long niveau_courant)
! 253: {
! 254: unsigned char *chaine;
! 255: unsigned char *registre;
! 256: unsigned char tampon[32 + 1];
! 257:
! 258: if (l_element_courant != NULL)
! 259: {
! 260: if (setjmp(contexte) == 0)
! 261: {
! 262: (*s_etat_processus).var_volatile_recursivite = -1;
! 263: ecriture_pile(s_etat_processus, flux,
! 264: (*l_element_courant).suivant, niveau_courant + 1);
! 265:
! 266: if ((*s_etat_processus).var_volatile_recursivite > 0)
! 267: {
! 268: (*s_etat_processus).var_volatile_recursivite--;
! 269:
! 270: if ((*s_etat_processus).var_volatile_recursivite == 0)
! 271: {
! 272: if (fprintf(flux, "%lu: ...\n", niveau_courant) < 0)
! 273: {
! 274: (*s_etat_processus).erreur_systeme =
! 275: d_es_erreur_fichier;
! 276: return;
! 277: }
! 278:
! 279: while(l_element_courant != NULL)
! 280: {
! 281: l_element_courant = (*l_element_courant).suivant;
! 282: }
! 283: }
! 284:
! 285: return;
! 286: }
! 287:
! 288: (*s_etat_processus).var_volatile_recursivite = 0;
! 289: }
! 290: else
! 291: {
! 292: // Libération de n appels de la pile système qui permet de
! 293: // terminer la récursion sans autre dépassement de pile.
! 294:
! 295: (*s_etat_processus).var_volatile_recursivite = 64;
! 296: return;
! 297: }
! 298:
! 299: sprintf(tampon, "%lu: ", niveau_courant);
! 300:
! 301: if ((chaine = formateur(s_etat_processus, strlen(tampon),
! 302: (*l_element_courant).donnee)) == NULL)
! 303: {
! 304: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 305: return;
! 306: }
! 307:
! 308: if ((*(*l_element_courant).donnee).type == CHN)
! 309: {
! 310: registre = chaine;
! 311:
! 312: if ((chaine = (unsigned char *) malloc((strlen(registre) + 3) *
! 313: sizeof(unsigned char))) == NULL)
! 314: {
! 315: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 316: return;
! 317: }
! 318:
! 319: sprintf(chaine, "\"%s\"", registre);
! 320: free(registre);
! 321: }
! 322:
! 323: if (fprintf(flux, "%lu: %s\n", niveau_courant, chaine) < 0)
! 324: {
! 325: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
! 326: return;
! 327: }
! 328:
! 329: free(chaine);
! 330: }
! 331:
! 332: return;
! 333: }
! 334:
! 335:
! 336: /*
! 337: ================================================================================
! 338: Procédure imprimant la pile opérationnelle
! 339: ================================================================================
! 340: Entrée : méthode 'C' = compacte, 'E' = étendue
! 341: --------------------------------------------------------------------------------
! 342: Sortie :
! 343: --------------------------------------------------------------------------------
! 344: Effets de bord : néant
! 345: ================================================================================
! 346: */
! 347:
! 348: void
! 349: impression_pile(struct_processus *s_etat_processus,
! 350: struct_liste_chainee *l_element_courant, unsigned char methode,
! 351: unsigned long niveau_courant)
! 352: {
! 353: struct_objet s_objet;
! 354:
! 355: unsigned char *chaine;
! 356: unsigned char *registre;
! 357: unsigned char tampon[32 + 1];
! 358:
! 359: if (l_element_courant != NULL)
! 360: {
! 361: if (setjmp(contexte) == 0)
! 362: {
! 363: (*s_etat_processus).var_volatile_recursivite = -1;
! 364: impression_pile(s_etat_processus, (*l_element_courant).suivant,
! 365: methode, niveau_courant + 1);
! 366:
! 367: if ((*s_etat_processus).var_volatile_recursivite > 0)
! 368: {
! 369: (*s_etat_processus).var_volatile_recursivite--;
! 370:
! 371: if ((*s_etat_processus).var_volatile_recursivite == 0)
! 372: {
! 373: while(l_element_courant != NULL)
! 374: {
! 375: l_element_courant = (*l_element_courant).suivant;
! 376: }
! 377: }
! 378:
! 379: return;
! 380: }
! 381:
! 382: (*s_etat_processus).var_volatile_recursivite = 0;
! 383: }
! 384: else
! 385: {
! 386: (*s_etat_processus).var_volatile_recursivite = 16;
! 387: return;
! 388: }
! 389:
! 390: if (methode == 'C')
! 391: {
! 392: s_objet.type = CHN;
! 393: sprintf(tampon, "%lu: ", niveau_courant);
! 394:
! 395: if ((chaine = formateur(s_etat_processus, strlen(tampon),
! 396: (*l_element_courant).donnee)) == NULL)
! 397: {
! 398: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 399: return;
! 400: }
! 401:
! 402: if ((*(*l_element_courant).donnee).type == CHN)
! 403: {
! 404: registre = chaine;
! 405:
! 406: if ((chaine = (unsigned char *) malloc((strlen(registre) + 3) *
! 407: sizeof(unsigned char))) == NULL)
! 408: {
! 409: (*s_etat_processus).erreur_systeme =
! 410: d_es_allocation_memoire;
! 411: return;
! 412: }
! 413:
! 414: sprintf(chaine, "\"%s\"", registre);
! 415: free(registre);
! 416: }
! 417:
! 418: if ((s_objet.objet = malloc((strlen(chaine) + 64) *
! 419: sizeof(unsigned char))) == NULL)
! 420: {
! 421: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 422: return;
! 423: }
! 424:
! 425: sprintf((unsigned char *) s_objet.objet,
! 426: "\n\\noindent\\begin{verbatim}\n%lu: %s\n\\end{verbatim}",
! 427: niveau_courant, chaine);
! 428: free(chaine);
! 429:
! 430: formateur_tex(s_etat_processus, &s_objet, 'V');
! 431: free(s_objet.objet);
! 432: }
! 433: else
! 434: {
! 435: formateur_tex(s_etat_processus, (*l_element_courant).donnee, 'N');
! 436: }
! 437: }
! 438:
! 439: return;
! 440: }
! 441:
! 442: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>