Annotation of rpl/src/gestion_pile_systeme.c, revision 1.66
1.1 bertrand 1: /*
2: ================================================================================
1.65 bertrand 3: RPL/2 (R) version 4.1.17
1.66 ! bertrand 4: Copyright (C) 1989-2014 Dr. BERTRAND Joël
1.1 bertrand 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:
1.19 bertrand 23: #include "rpl-conv.h"
1.1 bertrand 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_systeme(struct_processus *s_etat_processus)
40: {
41: (*s_etat_processus).estimation_taille_pile_systeme_tampon =
1.56 bertrand 42: (((double) (*s_etat_processus)
43: .estimation_taille_pile_systeme_tampon) *
44: ((double) 0.9)) + (((double) (*s_etat_processus)
45: .hauteur_pile_systeme) * ((double) 0.1));
1.1 bertrand 46: return;
47: }
48:
49:
50: /*
51: ================================================================================
52: Procédure d'empilement d'un nouvel élément
53: ================================================================================
54: Entrée :
55: --------------------------------------------------------------------------------
56: Sortie :
57: --------------------------------------------------------------------------------
58: Effets de bord : néant
59: ================================================================================
60: */
61:
62: void
63: empilement_pile_systeme(struct_processus *s_etat_processus)
64: {
65: struct_liste_pile_systeme *l_ancienne_base_liste;
66: struct_liste_pile_systeme *l_nouvelle_base_liste;
67:
68: l_ancienne_base_liste = (*s_etat_processus).l_base_pile_systeme;
69:
70: if ((*s_etat_processus).debug == d_vrai)
71: if (((*s_etat_processus).type_debug &
72: d_debug_pile_systeme) != 0)
73: {
74: if (strlen((*s_etat_processus).instruction_courante) != 0)
75: {
76: if ((*s_etat_processus).langue == 'F')
77: {
78: printf("[%d] Empilement sur la pile système à la suite de "
79: "l'instruction %s\n", (int) getpid(),
80: (*s_etat_processus).instruction_courante);
81: }
82: else
83: {
84: printf("[%d] Pushing on system stack (instruction %s)\n",
85: (int) getpid(),
86: (*s_etat_processus).instruction_courante);
87: }
88: }
89: else
90: {
91: if ((*s_etat_processus).langue == 'F')
92: {
93: printf("[%d] Empilement sur la pile système\n",
94: (int) getpid());
95: }
96: else
97: {
98: printf("[%d] Pushing on system stack\n", (int) getpid());
99: }
100: }
101:
102: fflush(stdout);
103: }
104:
105: if ((*s_etat_processus).pile_systeme_tampon == NULL)
106: {
107: // Tampon vide, on alloue un élément.
108:
109: if ((l_nouvelle_base_liste = malloc(sizeof(struct_liste_pile_systeme)))
110: == NULL)
111: {
112: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
113: return;
114: }
115: }
116: else
117: {
118: // Tampon utilisable, on retire un élément du tampon.
119:
120: l_nouvelle_base_liste = (*s_etat_processus).pile_systeme_tampon;
121: (*s_etat_processus).pile_systeme_tampon =
122: (*l_nouvelle_base_liste).suivant;
123: (*s_etat_processus).taille_pile_systeme_tampon--;
124: }
125:
126: (*s_etat_processus).hauteur_pile_systeme++;
127: (*s_etat_processus).l_base_pile_systeme = l_nouvelle_base_liste;
128: (*(*s_etat_processus).l_base_pile_systeme).suivant =
129: l_ancienne_base_liste;
130:
131: (*(*s_etat_processus).l_base_pile_systeme).type_cloture = ' ';
132: (*(*s_etat_processus).l_base_pile_systeme).clause = ' ';
133: (*(*s_etat_processus).l_base_pile_systeme).adresse_retour = 0;
1.51 bertrand 134: (*(*s_etat_processus).l_base_pile_systeme).niveau_courant =
135: (*s_etat_processus).niveau_courant;
1.1 bertrand 136: (*(*s_etat_processus).l_base_pile_systeme).retour_definition = 'N';
137: (*(*s_etat_processus).l_base_pile_systeme).indice_boucle = NULL;
138: (*(*s_etat_processus).l_base_pile_systeme).limite_indice_boucle = NULL;
139: (*(*s_etat_processus).l_base_pile_systeme).objet_de_test = NULL;
140: (*(*s_etat_processus).l_base_pile_systeme).nom_variable = NULL;
141: (*(*s_etat_processus).l_base_pile_systeme).pointeur_objet_retour = NULL;
142: (*(*s_etat_processus).l_base_pile_systeme)
143: .origine_routine_evaluation = 'N';
144: (*(*s_etat_processus).l_base_pile_systeme).arret_si_exception =
145: (*s_etat_processus).arret_si_exception;
146: (*(*s_etat_processus).l_base_pile_systeme).creation_variables_statiques
147: = (*s_etat_processus).creation_variables_statiques;
148: (*(*s_etat_processus).l_base_pile_systeme).creation_variables_partagees
149: = (*s_etat_processus).creation_variables_partagees;
150: (*(*s_etat_processus).l_base_pile_systeme).evaluation_expression =
151: d_faux;
152:
153: (*s_etat_processus).erreur_systeme = d_es;
154: (*s_etat_processus).creation_variables_statiques = d_faux;
155: (*s_etat_processus).creation_variables_partagees = d_faux;
156:
157: return;
158: }
159:
160:
161: /*
162: ================================================================================
163: Procédure de dépilement d'un élément
164: ================================================================================
165: Entrée :
166: --------------------------------------------------------------------------------
167: Sortie :
168: --------------------------------------------------------------------------------
169: Effets de bord : néant
170: ================================================================================
171: */
172:
173: void
174: depilement_pile_systeme(struct_processus *s_etat_processus)
175: {
176: struct_liste_pile_systeme *l_ancienne_base_liste;
177: struct_liste_pile_systeme *l_nouvelle_base_liste;
178:
179: if ((*s_etat_processus).debug == d_vrai)
180: if (((*s_etat_processus).type_debug &
181: d_debug_pile_systeme) != 0)
182: {
183: if (strlen((*s_etat_processus).instruction_courante) != 0)
184: {
185: if ((*s_etat_processus).langue == 'F')
186: {
187: printf("[%d] Dépilement de la pile système à la suite "
188: "de l'instruction %s\n", (int) getpid(),
189: (*s_etat_processus).instruction_courante);
190: }
191: else
192: {
193: printf("[%d] Pulling from system stack (instruction %s)\n",
194: (int) getpid(),
195: (*s_etat_processus).instruction_courante);
196: }
197: }
198: else
199: {
200: if ((*s_etat_processus).langue == 'F')
201: {
202: printf("[%d] Dépilement de la pile système\n",
203: (int) getpid());
204: }
205: else
206: {
207: printf("[%d] Pulling from system stack\n", (int) getpid());
208: }
209: }
210:
211: fflush(stdout);
212: }
213:
214: if ((*s_etat_processus).l_base_pile_systeme == NULL)
215: {
216: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
217: }
218: else
219: {
220: (*s_etat_processus).hauteur_pile_systeme--;
221: l_ancienne_base_liste = (*s_etat_processus).l_base_pile_systeme;
222: l_nouvelle_base_liste = (*l_ancienne_base_liste).suivant;
223:
224: (*s_etat_processus).l_base_pile_systeme = l_nouvelle_base_liste;
225: (*s_etat_processus).erreur_systeme = d_es;
226:
227: // On positionne le drapeau de création des variables statiques.
228:
229: (*s_etat_processus).creation_variables_statiques =
230: (*l_ancienne_base_liste).creation_variables_statiques;
231: (*s_etat_processus).creation_variables_partagees =
232: (*l_ancienne_base_liste).creation_variables_partagees;
233:
234: if ((*l_ancienne_base_liste).nom_variable != NULL)
235: {
236: free((*l_ancienne_base_liste).nom_variable);
237: }
238:
239: liberation(s_etat_processus, (*l_ancienne_base_liste).indice_boucle);
240: liberation(s_etat_processus,
241: (*l_ancienne_base_liste).limite_indice_boucle);
242: liberation(s_etat_processus, (*l_ancienne_base_liste).objet_de_test);
243:
244: if ((*s_etat_processus).taille_pile_systeme_tampon <= (10 *
245: ((*s_etat_processus).estimation_taille_pile_systeme_tampon
246: + 1)))
247: {
248: // Enregistrement de la structure pour un usage ultérieur.
249:
250: (*l_ancienne_base_liste).suivant =
251: (*s_etat_processus).pile_systeme_tampon;
252: (*s_etat_processus).pile_systeme_tampon = l_ancienne_base_liste;
253: (*s_etat_processus).taille_pile_systeme_tampon++;
254: }
255: else
256: {
257: // Libération car le tampon est plein.
258:
259: free(l_ancienne_base_liste);
260: }
261: }
262:
263: return;
264: }
265:
1.7 bertrand 266:
267: /*
268: ================================================================================
269: Procédure d'effacement de la pile système
270: ================================================================================
271: Entrée :
272: --------------------------------------------------------------------------------
273: Sortie :
274: --------------------------------------------------------------------------------
275: Effets de bord : néant
276: ================================================================================
277: */
278:
279: void
280: effacement_pile_systeme(struct_processus *s_etat_processus)
281: {
282: while((*s_etat_processus).l_base_pile_systeme != NULL)
283: {
284: depilement_pile_systeme(s_etat_processus);
285: }
286:
287: return;
288: }
289:
1.12 bertrand 290:
291: /*
292: ================================================================================
293: Procédure d'affichage de la pile système
294: ================================================================================
295: Entrée :
296: --------------------------------------------------------------------------------
297: Sortie :
298: --------------------------------------------------------------------------------
299: Effets de bord : néant
300: ================================================================================
301: */
302:
303: void
304: trace(struct_processus *s_etat_processus, FILE *flux)
305: {
1.15 bertrand 306: integer8 i;
1.56 bertrand 307: integer8 j;
308: integer8 candidat;
1.51 bertrand 309: integer8 candidat8;
310: integer8 delta;
1.56 bertrand 311: integer8 nb_variables;
1.16 bertrand 312:
1.51 bertrand 313: struct_liste_chainee *l_element_expression;
1.15 bertrand 314:
1.51 bertrand 315: struct_liste_pile_systeme *l_element_courant;
1.26 bertrand 316:
1.51 bertrand 317: struct_tableau_variables *tableau;
1.12 bertrand 318:
1.15 bertrand 319: unsigned char *tampon;
1.12 bertrand 320:
321: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
322: i = 0;
323:
324: while(l_element_courant != NULL)
325: {
326: i++;
327: l_element_courant = (*l_element_courant).suivant;
328: }
329:
330: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
331: flockfile(flux);
332:
1.51 bertrand 333: nb_variables = nombre_variables(s_etat_processus);
334:
1.56 bertrand 335: if ((tableau = malloc(((size_t) nb_variables) *
336: sizeof(struct_tableau_variables))) == NULL)
1.51 bertrand 337: {
338: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
339: return;
340: }
341:
342: liste_variables(s_etat_processus, tableau);
343:
1.12 bertrand 344: if ((flux == stderr) || (flux == stdout))
345: {
346: fprintf(flux, "+++Backtrace\n");
347: }
348:
349: while(l_element_courant != NULL)
350: {
1.54 bertrand 351: fprintf(flux, "%lld : address # %016Xh\n", i--, l_element_courant);
1.12 bertrand 352:
1.51 bertrand 353: if ((*l_element_courant).creation_variables_statiques == d_vrai)
354: {
355: fprintf(flux, " Variables = static\n");
356: }
357: else if ((*l_element_courant).creation_variables_partagees == d_vrai)
358: {
359: fprintf(flux, " Variables = shared\n");
360: }
361: else
362: {
363: fprintf(flux, " Variables = automatic\n");
364: }
365:
366: if ((*l_element_courant).arret_si_exception == d_vrai)
367: {
368: fprintf(flux, " In exception = abort\n");
369: }
370: else
371: {
372: fprintf(flux, " In exception = catch\n");
373: }
1.12 bertrand 374:
1.51 bertrand 375: if ((*l_element_courant).clause != ' ')
1.12 bertrand 376: {
1.51 bertrand 377: fprintf(flux, " Structure = ");
1.12 bertrand 378:
1.51 bertrand 379: switch((*l_element_courant).clause)
1.12 bertrand 380: {
1.51 bertrand 381: case 'I':
382: fprintf(flux, "IF\n");
383: break;
384:
385: case 'R':
386: fprintf(flux, "IFERR\n");
387: break;
388:
389: case 'X':
390: fprintf(flux, "exception caught by IFERR\n");
391: break;
392:
393: case 'T':
394: fprintf(flux, "THEN\n");
395: break;
396:
397: case 'E':
398: fprintf(flux, "ELSE\n");
399: break;
400:
401: case 'Z':
402: fprintf(flux, "ELSE (false condition)\n");
403: break;
404:
405: case 'D':
406: fprintf(flux, "DO\n");
407: break;
408:
409: case 'U':
410: fprintf(flux, "UNTIL\n");
411: break;
412:
413: case 'W':
414: fprintf(flux, "WHILE\n");
415: break;
416:
417: case 'M':
418: fprintf(flux, "WHILE (false condition)\n");
419: break;
420:
421: case 'S':
422: fprintf(flux, "SELECT\n");
423: break;
424:
425: case 'K':
426: fprintf(flux, "CASE (no true condition)\n");
427: break;
428:
429: case 'C':
430: fprintf(flux, "CASE (one or more true conditions)\n");
431: break;
432:
433: case 'Q':
434: fprintf(flux, "CASE (treatment of a true condition)\n");
435: break;
436:
437: case 'F':
438: fprintf(flux, "CASE (treatment of default case)\n");
439: break;
1.16 bertrand 440: }
1.51 bertrand 441: }
442:
443: if ((*l_element_courant).type_cloture != ' ')
444: {
445: fprintf(flux, " Next close = ");
446:
447: switch((*l_element_courant).type_cloture)
1.16 bertrand 448: {
1.51 bertrand 449: case 'C':
450: fprintf(flux, "SELECT\n");
451: break;
452:
453: case 'D':
454: fprintf(flux, "DO\n");
455: break;
456:
457: case 'I':
458: fprintf(flux, "IF\n");
459: break;
460:
461: case 'J':
462: fprintf(flux, "IFERR\n");
463: break;
464:
465: case 'K':
466: fprintf(flux, "CASE\n");
467: break;
468:
469: case 'W':
470: fprintf(flux, "WHILE\n");
471: break;
472:
473: case 'Q':
474: fprintf(flux, "CRITICAL\n");
475: break;
476:
477: case 'F':
478: fprintf(flux, "FOR\n");
479: break;
480:
481: case 'S':
482: fprintf(flux, "START\n");
483: break;
484:
485: case 'L':
486: fprintf(flux, "internal loop\n");
487: break;
488:
489: case 'A':
490: fprintf(flux, "FORALL\n");
491: break;
492: }
493: }
494:
1.60 bertrand 495: fprintf(flux, " Level = %lld\n",
496: (long long int) (*l_element_courant).niveau_courant);
1.12 bertrand 497:
1.58 bertrand 498: if ((*l_element_courant).retour_definition == 'Y')
1.51 bertrand 499: {
500: fprintf(flux, " Return = yes\n");
501:
502: if ((*l_element_courant).origine_routine_evaluation == 'Y')
503: {
504: if ((*l_element_courant).pointeur_objet_retour != NULL)
1.12 bertrand 505: {
1.51 bertrand 506: fprintf(flux, " Come from = compiled code ");
507: fprintf(flux, "(address # %016Xh)\n", (*l_element_courant)
508: .pointeur_objet_retour);
1.16 bertrand 509:
510: // Calcul de la routine de départ
511:
1.51 bertrand 512: candidat = -1;
1.16 bertrand 513:
1.51 bertrand 514: for(j = 0; j < nb_variables; j++)
1.16 bertrand 515: {
1.51 bertrand 516: if (((*(tableau[j].objet)).type == RPN) ||
517: ((*(tableau[j].objet)).type == ALG))
1.16 bertrand 518: {
1.51 bertrand 519: l_element_expression = (*(tableau[j].objet)).objet;
520:
521: while(l_element_expression != NULL)
522: {
523: if (l_element_expression == (*l_element_courant)
524: .pointeur_objet_retour)
525: {
526: candidat = j;
527: break;
528: }
529:
530: l_element_expression =
531: (*l_element_expression).suivant;
532: }
1.16 bertrand 533:
1.51 bertrand 534: if (candidat != -1)
1.16 bertrand 535: {
1.51 bertrand 536: break;
1.16 bertrand 537: }
538: }
539: }
540:
1.51 bertrand 541: if (candidat != -1)
1.16 bertrand 542: {
1.51 bertrand 543: fprintf(flux, " = %s [",
544: tableau[candidat].nom);
545:
546: if ((*(tableau[candidat].objet)).type == RPN)
547: {
548: fprintf(flux, "definition");
549: }
550: else if ((*(tableau[candidat].objet)).type == ALG)
551: {
552: fprintf(flux, "algebraic");
553: }
554: else if ((*(tableau[candidat].objet)).type == NOM)
555: {
556: fprintf(flux, "name");
557: }
558: else
559: {
560: fprintf(flux, "unknown");
561: }
562:
563: fprintf(flux, "]\n");
1.16 bertrand 564: }
565: else
566: {
1.51 bertrand 567: fprintf(flux, " = "
568: "optimized definition\n");
1.16 bertrand 569: }
1.12 bertrand 570: }
1.16 bertrand 571: else
1.12 bertrand 572: {
1.53 bertrand 573: fprintf(flux, " Come from = compiled code\n");
1.51 bertrand 574: fprintf(flux, " = "
575: "optimized definition\n");
1.12 bertrand 576: }
577: }
578: else
579: {
1.51 bertrand 580: fprintf(flux, " Come from = interpreted code ");
1.12 bertrand 581:
1.51 bertrand 582: if ((*l_element_courant).adresse_retour != 0)
1.12 bertrand 583: {
1.51 bertrand 584: fprintf(flux, "(offset # %016Xh)\n", (*l_element_courant)
585: .adresse_retour);
1.16 bertrand 586:
587: // Calcul de la routine de départ
588:
1.51 bertrand 589: candidat8 = (*s_etat_processus)
1.26 bertrand 590: .longueur_definitions_chainees;
1.51 bertrand 591: candidat = -1;
1.16 bertrand 592:
1.51 bertrand 593: for(j = 0; j < nb_variables; j++)
1.16 bertrand 594: {
1.51 bertrand 595: if ((*(tableau[j].objet)).type == ADR)
1.16 bertrand 596: {
1.51 bertrand 597: delta = (*l_element_courant).adresse_retour
1.56 bertrand 598: - (*((integer8 *)
1.51 bertrand 599: (*(tableau[j].objet)).objet));
600:
601: if ((delta >= 0) && (delta < candidat8))
602: {
603: candidat8 = delta;
604: candidat = j;
605: }
1.16 bertrand 606: }
607: }
608:
1.51 bertrand 609: if (candidat != -1)
1.16 bertrand 610: {
1.51 bertrand 611: fprintf(flux, " = %s\n",
612: tableau[candidat].nom);
1.16 bertrand 613: }
614: else
615: {
1.51 bertrand 616: fprintf(flux, " = "
617: "unknown definition\n");
1.16 bertrand 618: }
1.12 bertrand 619: }
1.62 bertrand 620: else if ((*l_element_courant).niveau_courant == 0)
1.51 bertrand 621: {
622: fprintf(flux, "\n");
623: fprintf(flux, " = RPL/2 "
624: "initialization\n");
625: }
1.62 bertrand 626: else
627: {
628: fprintf(flux, "\n");
629: }
1.12 bertrand 630: }
631: }
1.51 bertrand 632: else
633: {
634: fprintf(flux, " Return = no\n");
635: }
1.12 bertrand 636:
1.57 bertrand 637: if (((*l_element_courant).indice_boucle != NULL) &&
638: ((*l_element_courant).type_cloture != 'A'))
1.15 bertrand 639: {
1.51 bertrand 640: tampon = formateur(s_etat_processus, 24,
1.15 bertrand 641: (*l_element_courant).indice_boucle);
1.51 bertrand 642: fprintf(flux, " Index = %s\n", tampon);
1.15 bertrand 643: free(tampon);
644: }
645:
646: if ((*l_element_courant).limite_indice_boucle != NULL)
647: {
1.51 bertrand 648: tampon = formateur(s_etat_processus, 24,
1.15 bertrand 649: (*l_element_courant).limite_indice_boucle);
1.51 bertrand 650: fprintf(flux, " Limit = %s\n", tampon);
1.15 bertrand 651: free(tampon);
652: }
653:
654: if ((*l_element_courant).objet_de_test != NULL)
655: {
1.51 bertrand 656: tampon = formateur(s_etat_processus, 24,
1.15 bertrand 657: (*l_element_courant).objet_de_test);
1.51 bertrand 658: fprintf(flux, " Test object = %s\n", tampon);
1.15 bertrand 659: free(tampon);
660: }
661:
662: if ((*l_element_courant).nom_variable != NULL)
663: {
1.51 bertrand 664: fprintf(flux, " Variable name = %s\n",
1.15 bertrand 665: (*l_element_courant).nom_variable);
666: }
667:
1.51 bertrand 668: fprintf(flux, "\n");
669:
1.12 bertrand 670: l_element_courant = (*l_element_courant).suivant;
671: }
672:
673: funlockfile(flux);
674:
1.51 bertrand 675: free(tableau);
676:
1.12 bertrand 677: return;
678: }
679:
1.1 bertrand 680: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>