![]() ![]() | ![]() |
Passage de la branche 4.1 en branche stable.
1: /* 2: ================================================================================ 3: RPL/2 (R) version 4.1.0 4: Copyright (C) 1989-2011 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: if ((*s_etat_processus).hauteur_pile_operationnelle > 49: (*s_etat_processus).estimation_taille_pile_tampon) 50: { 51: (*s_etat_processus).estimation_taille_pile_tampon = 52: (*s_etat_processus).estimation_taille_pile_tampon; 53: } 54: else 55: { 56: (*s_etat_processus).estimation_taille_pile_tampon = 57: ((*s_etat_processus).estimation_taille_pile_tampon * 58: ((double) 0.95)) + ((*s_etat_processus) 59: .hauteur_pile_operationnelle * ((double) 0.05)); 60: } 61: 62: return; 63: } 64: 65: 66: /* 67: ================================================================================ 68: Procédure d'empilement d'un nouvel élément 69: ================================================================================ 70: Entrée : 71: -------------------------------------------------------------------------------- 72: Sortie : 73: -------------------------------------------------------------------------------- 74: Effets de bord : néant 75: ================================================================================ 76: */ 77: 78: logical1 79: empilement(struct_processus *s_etat_processus, 80: struct_liste_chainee **l_base_pile, struct_objet *s_objet) 81: { 82: struct_liste_chainee *l_ancienne_base_liste; 83: struct_liste_chainee *l_nouvelle_base_liste; 84: 85: logical1 erreur; 86: 87: l_ancienne_base_liste = *l_base_pile; 88: 89: if ((*s_etat_processus).pile_tampon == NULL) 90: { 91: // Tampon vide, on alloue un élément. 92: 93: if ((l_nouvelle_base_liste = malloc(sizeof(struct_liste_chainee))) 94: == NULL) 95: { 96: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 97: return(d_erreur); 98: } 99: } 100: else 101: { 102: // Tampon utilisable, on retire un élément du tampon. 103: 104: l_nouvelle_base_liste = (*s_etat_processus).pile_tampon; 105: (*s_etat_processus).pile_tampon = (*l_nouvelle_base_liste).suivant; 106: (*s_etat_processus).taille_pile_tampon--; 107: } 108: 109: *l_base_pile = l_nouvelle_base_liste; 110: (**l_base_pile).donnee = s_objet; 111: (**l_base_pile).suivant = l_ancienne_base_liste; 112: 113: erreur = d_absence_erreur; 114: 115: /* 116: -- Ne considère que la pile opérationnelle ------------------------------------- 117: */ 118: 119: if ((*s_etat_processus).l_base_pile == *l_base_pile) 120: { 121: (*s_etat_processus).hauteur_pile_operationnelle++; 122: estimation_taille_pile(s_etat_processus); 123: 124: if ((*s_etat_processus).debug == d_vrai) 125: if (((*s_etat_processus).type_debug & 126: d_debug_pile_utilisateur) != 0) 127: { 128: if ((*s_etat_processus).langue == 'F') 129: { 130: printf("[%d] Empilement de type %d " 131: "(profondeur %lu)\n", (int) getpid(), 132: (*s_objet).type, 133: (*s_etat_processus).hauteur_pile_operationnelle); 134: } 135: else 136: { 137: printf("[%d] Pushing a type %d object " 138: "(depth %lu)\n", (int) getpid(), (*s_objet).type, 139: (*s_etat_processus).hauteur_pile_operationnelle); 140: } 141: 142: fflush(stdout); 143: } 144: } 145: 146: return erreur; 147: } 148: 149: 150: /* 151: ================================================================================ 152: Procédure de dépilement d'un élément. L'emplacement est libéré dans la pile. 153: ================================================================================ 154: Entrée : 155: -------------------------------------------------------------------------------- 156: Sortie : 157: -------------------------------------------------------------------------------- 158: Effets de bord : néant 159: ================================================================================ 160: */ 161: 162: logical1 163: depilement(struct_processus *s_etat_processus, 164: struct_liste_chainee **l_base_pile, struct_objet **s_objet) 165: { 166: struct_liste_chainee *l_ancienne_base_liste; 167: struct_liste_chainee *l_nouvelle_base_liste; 168: 169: logical1 erreur; 170: 171: if (*l_base_pile == NULL) 172: { 173: (*s_etat_processus).erreur_execution = d_ex_pile_vide; 174: erreur = d_erreur; 175: } 176: else 177: { 178: 179: /* 180: -- Ne considère que la pile opérationnelle ------------------------------------- 181: */ 182: 183: l_ancienne_base_liste = *l_base_pile; 184: *s_objet = (*l_ancienne_base_liste).donnee; 185: 186: if ((*s_etat_processus).l_base_pile == *l_base_pile) 187: { 188: if ((*s_etat_processus).debug == d_vrai) 189: if (((*s_etat_processus).type_debug & 190: d_debug_pile_utilisateur) != 0) 191: { 192: if ((*s_etat_processus).langue == 'F') 193: { 194: printf("[%d] Dépilement de type %d " 195: "(profondeur %lu)\n", (int) getpid(), 196: (*(*s_objet)).type, 197: (*s_etat_processus).hauteur_pile_operationnelle); 198: } 199: else 200: { 201: printf("[%d] Pulling a type %d object " 202: "(depth %lu)\n", (int) getpid(), (*(*s_objet)).type, 203: (*s_etat_processus).hauteur_pile_operationnelle); 204: } 205: 206: fflush(stdout); 207: } 208: 209: (*s_etat_processus).hauteur_pile_operationnelle--; 210: estimation_taille_pile(s_etat_processus); 211: } 212: 213: l_nouvelle_base_liste = (*l_ancienne_base_liste).suivant; 214: 215: *l_base_pile = l_nouvelle_base_liste; 216: erreur = d_absence_erreur; 217: 218: if ((*s_etat_processus).taille_pile_tampon <= (10 * ((*s_etat_processus) 219: .estimation_taille_pile_tampon + 1))) 220: { 221: // Enregistrement de la structure pour usage ultérieur. 222: 223: (*l_ancienne_base_liste).donnee = NULL; 224: (*l_ancienne_base_liste).suivant = (*s_etat_processus).pile_tampon; 225: (*s_etat_processus).pile_tampon = l_ancienne_base_liste; 226: (*s_etat_processus).taille_pile_tampon++; 227: } 228: else 229: { 230: // Libération car le tampon est plein. 231: 232: free(l_ancienne_base_liste); 233: } 234: } 235: 236: return erreur; 237: } 238: 239: 240: /* 241: ================================================================================ 242: Procédures affichant la pile opérationnelle 243: ================================================================================ 244: Entrée : 245: -------------------------------------------------------------------------------- 246: Sortie : 247: -------------------------------------------------------------------------------- 248: Effets de bord : néant 249: ================================================================================ 250: */ 251: 252: void 253: affichage_pile(struct_processus *s_etat_processus, struct_liste_chainee 254: *l_element_courant, unsigned long niveau_courant) 255: { 256: unsigned char registre; 257: 258: registre = (*s_etat_processus).autorisation_conversion_chaine; 259: (*s_etat_processus).autorisation_conversion_chaine = 'N'; 260: 261: ecriture_pile(s_etat_processus, stdout, l_element_courant, niveau_courant); 262: 263: (*s_etat_processus).autorisation_conversion_chaine = registre; 264: return; 265: } 266: 267: void 268: ecriture_pile(struct_processus *s_etat_processus, file *flux, 269: struct_liste_chainee *l_element_courant, unsigned long niveau_courant) 270: { 271: unsigned char *chaine; 272: unsigned char *registre; 273: unsigned char tampon[32 + 1]; 274: 275: if (l_element_courant != NULL) 276: { 277: if (setjmp(contexte) == 0) 278: { 279: (*s_etat_processus).var_volatile_recursivite = -1; 280: ecriture_pile(s_etat_processus, flux, 281: (*l_element_courant).suivant, niveau_courant + 1); 282: 283: if ((*s_etat_processus).var_volatile_recursivite > 0) 284: { 285: (*s_etat_processus).var_volatile_recursivite--; 286: 287: if ((*s_etat_processus).var_volatile_recursivite == 0) 288: { 289: if (fprintf(flux, "%lu: ...\n", niveau_courant) < 0) 290: { 291: (*s_etat_processus).erreur_systeme = 292: d_es_erreur_fichier; 293: return; 294: } 295: 296: while(l_element_courant != NULL) 297: { 298: l_element_courant = (*l_element_courant).suivant; 299: } 300: } 301: 302: return; 303: } 304: 305: (*s_etat_processus).var_volatile_recursivite = 0; 306: } 307: else 308: { 309: // Libération de n appels de la pile système qui permet de 310: // terminer la récursion sans autre dépassement de pile. 311: 312: (*s_etat_processus).var_volatile_recursivite = 64; 313: return; 314: } 315: 316: sprintf(tampon, "%lu: ", niveau_courant); 317: 318: if ((chaine = formateur(s_etat_processus, strlen(tampon), 319: (*l_element_courant).donnee)) == NULL) 320: { 321: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 322: return; 323: } 324: 325: if ((*(*l_element_courant).donnee).type == CHN) 326: { 327: registre = chaine; 328: 329: if ((chaine = (unsigned char *) malloc((strlen(registre) + 3) * 330: sizeof(unsigned char))) == NULL) 331: { 332: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 333: return; 334: } 335: 336: sprintf(chaine, "\"%s\"", registre); 337: free(registre); 338: } 339: 340: if (fprintf(flux, "%lu: %s\n", niveau_courant, chaine) < 0) 341: { 342: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; 343: return; 344: } 345: 346: free(chaine); 347: } 348: 349: return; 350: } 351: 352: 353: /* 354: ================================================================================ 355: Procédure imprimant la pile opérationnelle 356: ================================================================================ 357: Entrée : méthode 'C' = compacte, 'E' = étendue 358: -------------------------------------------------------------------------------- 359: Sortie : 360: -------------------------------------------------------------------------------- 361: Effets de bord : néant 362: ================================================================================ 363: */ 364: 365: void 366: impression_pile(struct_processus *s_etat_processus, 367: struct_liste_chainee *l_element_courant, unsigned char methode, 368: unsigned long niveau_courant) 369: { 370: struct_objet s_objet; 371: 372: unsigned char *chaine; 373: unsigned char *registre; 374: unsigned char tampon[32 + 1]; 375: 376: if (l_element_courant != NULL) 377: { 378: if (setjmp(contexte) == 0) 379: { 380: (*s_etat_processus).var_volatile_recursivite = -1; 381: impression_pile(s_etat_processus, (*l_element_courant).suivant, 382: methode, niveau_courant + 1); 383: 384: if ((*s_etat_processus).var_volatile_recursivite > 0) 385: { 386: (*s_etat_processus).var_volatile_recursivite--; 387: 388: if ((*s_etat_processus).var_volatile_recursivite == 0) 389: { 390: while(l_element_courant != NULL) 391: { 392: l_element_courant = (*l_element_courant).suivant; 393: } 394: } 395: 396: return; 397: } 398: 399: (*s_etat_processus).var_volatile_recursivite = 0; 400: } 401: else 402: { 403: (*s_etat_processus).var_volatile_recursivite = 16; 404: return; 405: } 406: 407: if (methode == 'C') 408: { 409: s_objet.type = CHN; 410: sprintf(tampon, "%lu: ", niveau_courant); 411: 412: if ((chaine = formateur(s_etat_processus, strlen(tampon), 413: (*l_element_courant).donnee)) == NULL) 414: { 415: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 416: return; 417: } 418: 419: if ((*(*l_element_courant).donnee).type == CHN) 420: { 421: registre = chaine; 422: 423: if ((chaine = (unsigned char *) malloc((strlen(registre) + 3) * 424: sizeof(unsigned char))) == NULL) 425: { 426: (*s_etat_processus).erreur_systeme = 427: d_es_allocation_memoire; 428: return; 429: } 430: 431: sprintf(chaine, "\"%s\"", registre); 432: free(registre); 433: } 434: 435: if ((s_objet.objet = malloc((strlen(chaine) + 64) * 436: sizeof(unsigned char))) == NULL) 437: { 438: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 439: return; 440: } 441: 442: sprintf((unsigned char *) s_objet.objet, 443: "\n\\noindent\\begin{verbatim}\n%lu: %s\n\\end{verbatim}", 444: niveau_courant, chaine); 445: free(chaine); 446: 447: formateur_tex(s_etat_processus, &s_objet, 'V'); 448: free(s_objet.objet); 449: } 450: else 451: { 452: formateur_tex(s_etat_processus, (*l_element_courant).donnee, 'N'); 453: } 454: } 455: 456: return; 457: } 458: 459: // vim: ts=4