![]() ![]() | ![]() |
1.1 bertrand 1: /*
2: ================================================================================
1.2 ! bertrand 3: RPL/2 (R) version 4.0.10
1.1 bertrand 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: Routine de création d'une nouvelle variable
29: Entrée : autorisation_creation_variable_statique vaut 'V' ou 'S'.
30: Dans le cas 'V', la variable est volatile.
31: Dans le cas 'S', elle est statique.
32: Entrée : autorisation_creation_variable_partagee vaut 'P' ou 'S'.
33: Dans le cas 'P', la variable est privée.
34: Dans le cas 'S', elle est partagée.
35: --------------------------------------------------------------------------------
36: Sortie :
37: --------------------------------------------------------------------------------
38: Effets de bords : néant
39: ================================================================================
40: */
41:
42: logical1
43: creation_variable(struct_processus *s_etat_processus,
44: struct_variable *s_variable,
45: unsigned char autorisation_creation_variable_statique,
46: unsigned char autorisation_creation_variable_partagee)
47: {
48: long i;
49:
50: struct_variable *s_nouvelle_base;
51:
52: (*s_etat_processus).nombre_variables++;
53:
54: if ((*s_etat_processus).nombre_variables > (*s_etat_processus)
55: .nombre_variables_allouees)
56: {
57: // La nouvelle variable ne tient pas dans la table courante. Il
58: // faut donc en augmenter la taille.
59:
60: if ((*s_etat_processus).nombre_variables_allouees == 0)
61: {
62: (*s_etat_processus).nombre_variables_allouees =
63: (*s_etat_processus).nombre_variables;
64: }
65: else
66: {
67: while((*s_etat_processus).nombre_variables >
68: (*s_etat_processus).nombre_variables_allouees)
69: {
70: (*s_etat_processus).nombre_variables_allouees *= 2;
71: }
72: }
73:
74: if ((s_nouvelle_base = realloc((*s_etat_processus).s_liste_variables,
75: (*s_etat_processus).nombre_variables_allouees *
76: sizeof(struct_variable))) == NULL)
77: {
78: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
79: (*s_etat_processus).nombre_variables--;
80: return(d_erreur);
81: }
82:
83: (*s_etat_processus).s_liste_variables = s_nouvelle_base;
84: }
85:
86: if ((*s_etat_processus).mode_execution_programme == 'Y')
87: {
88: (*s_variable).origine = 'P';
89: }
90: else
91: {
92: (*s_variable).origine = 'E';
93: }
94:
95: if ((*s_variable).niveau == 0)
96: {
97: // Un point d'entrée de définition est verrouillé.
98:
99: if ((*s_variable).origine == 'P')
100: {
101: (*s_variable).variable_statique.adresse = 0;
102: (*s_variable).variable_partagee.adresse = 0;
103: }
104: else
105: {
106: (*s_variable).variable_statique.pointeur = NULL;
107: (*s_variable).variable_partagee.pointeur = NULL;
108: }
109:
110: (*s_variable).variable_verrouillee = d_vrai;
111: }
112: else if ((*s_variable).niveau == 1)
113: {
114: // Une variable globale ne peut être statique.
115:
116: if ((*s_variable).origine == 'P')
117: {
118: (*s_variable).variable_statique.adresse = 0;
119: (*s_variable).variable_partagee.adresse = 0;
120: }
121: else
122: {
123: (*s_variable).variable_statique.pointeur = NULL;
124: (*s_variable).variable_partagee.pointeur = NULL;
125: }
126:
127: (*s_variable).variable_verrouillee = d_faux;
128: }
129: else
130: {
131: // 0 -> variable volatile
132: // adresse de création -> variable statique
133:
134: if (autorisation_creation_variable_statique == 'V')
135: {
136: if (autorisation_creation_variable_partagee == 'S')
137: {
138: // On force la création d'une variable partagée
139:
140: if ((*s_variable).origine == 'P')
141: {
142: (*s_variable).variable_statique.adresse = 0;
143: (*s_variable).variable_partagee.adresse =
144: (*s_etat_processus).position_courante;
145: }
146: else
147: {
148: (*s_variable).variable_statique.pointeur = NULL;
149: (*s_variable).variable_partagee.pointeur =
150: (*s_etat_processus).objet_courant;
151: }
152: }
153: else
154: {
155: // On force la création d'une variable volatile
156:
157: if ((*s_variable).origine == 'P')
158: {
159: (*s_variable).variable_statique.adresse = 0;
160: (*s_variable).variable_partagee.adresse = 0;
161: }
162: else
163: {
164: (*s_variable).variable_statique.pointeur = NULL;
165: (*s_variable).variable_partagee.pointeur = NULL;
166: }
167: }
168: }
169: else
170: {
171: // On force la création d'une variable statique.
172:
173: if ((*s_variable).origine == 'P')
174: {
175: (*s_variable).variable_statique.adresse =
176: (*s_etat_processus).position_courante;
177: (*s_variable).variable_partagee.adresse = 0;
178: }
179: else
180: {
181: (*s_variable).variable_statique.pointeur =
182: (*s_etat_processus).objet_courant;
183: (*s_variable).variable_partagee.pointeur = 0;
184: }
185: }
186:
187: (*s_variable).variable_verrouillee = d_faux;
188: }
189:
190: /*
191: * Positionnement de la variable au bon endroit
192: */
193:
194: // Nous avons (*s_etat_processus).nombre_variables - 1 variables dans la
195: // table qui sera balayée de la fin vers le début.
196:
197: if ((*s_etat_processus).nombre_variables == 1)
198: {
199: (*s_etat_processus).s_liste_variables[0] = (*s_variable);
200: }
201: else
202: {
203: for(i = (*s_etat_processus).nombre_variables - 2; i >= 0; i--)
204: {
205: if (strcmp((*s_variable).nom,
206: (*s_etat_processus).s_liste_variables[i].nom) < 0)
207: {
208: (*s_etat_processus).s_liste_variables[i + 1] =
209: (*s_etat_processus).s_liste_variables[i];
210: }
211: else
212: {
213: break;
214: }
215: }
216:
217: (*s_etat_processus).s_liste_variables[i + 1] = (*s_variable);
218: }
219:
220: return(d_absence_erreur);
221: }
222:
223:
224: /*
225: ================================================================================
226: Procédure de retrait d'une variable de la base
227: ================================================================================
228: Entrée : type 'G' ou 'L' selon que l'on retire une variable locale (incluant
229: les globales) ou strictement globale.
230: --------------------------------------------------------------------------------
231: Sortie :
232: --------------------------------------------------------------------------------
233: Effets de bord : néant
234: ================================================================================
235: */
236:
237: logical1
238: retrait_variable(struct_processus *s_etat_processus,
239: unsigned char *nom_variable, unsigned char type)
240: {
241: struct_variable *s_nouvelle_base;
242:
243: logical1 erreur;
244:
245: unsigned long position_courante;
246: unsigned long position_supprimee;
247:
248: if (recherche_variable(s_etat_processus, nom_variable) == d_vrai)
249: {
250: if (type == 'G')
251: {
252: if ((*s_etat_processus).position_variable_courante > 0)
253: {
254: while(strcmp((*s_etat_processus).s_liste_variables
255: [(*s_etat_processus).position_variable_courante]
256: .nom, nom_variable) == 0)
257: {
258: (*s_etat_processus).position_variable_courante--;
259:
260: if ((*s_etat_processus).position_variable_courante >=
261: (*s_etat_processus).nombre_variables)
262: {
263: erreur = d_erreur;
264: (*s_etat_processus).erreur_execution =
265: d_ex_variable_non_definie;
266: return erreur;
267: }
268: }
269:
270: (*s_etat_processus).position_variable_courante++;
271: }
272:
273: if ((*s_etat_processus).s_liste_variables
274: [(*s_etat_processus).position_variable_courante]
275: .niveau != 1)
276: {
277: erreur = d_erreur;
278: (*s_etat_processus).erreur_execution =
279: d_ex_variable_non_definie;
280: return erreur;
281: }
282:
283: if ((*s_etat_processus).s_liste_variables
284: [(*s_etat_processus).position_variable_courante]
285: .variable_verrouillee == d_vrai)
286: {
287: erreur = d_erreur;
288: (*s_etat_processus).erreur_execution =
289: d_ex_variable_verrouillee;
290: return erreur;
291: }
292: }
293:
294: if ((*s_etat_processus).nombre_variables <
295: ((*s_etat_processus).nombre_variables_allouees / 2))
296: {
297: (*s_etat_processus).nombre_variables_allouees /= 2;
298:
299: // (*s_etat_processus).nombre_variables est forcément
300: // supérieur à 1 (la décrémentation est postérieure). Ce test
301: // est vrai lorsque le nombre de variables allouées est
302: // strictement supérieur à 2.
303:
304: if ((s_nouvelle_base =
305: realloc((*s_etat_processus).s_liste_variables,
306: (*s_etat_processus).nombre_variables_allouees *
307: sizeof(struct_variable))) == NULL)
308: {
309: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
310: return(d_erreur);
311: }
312:
313: (*s_etat_processus).s_liste_variables = s_nouvelle_base;
314: }
315:
316: position_supprimee = (*s_etat_processus).position_variable_courante;
317:
318: liberation(s_etat_processus, (*s_etat_processus).s_liste_variables
319: [position_supprimee].objet);
320: free((*s_etat_processus).s_liste_variables[position_supprimee].nom);
321:
322: (*s_etat_processus).nombre_variables--;
323:
324: for(position_courante = position_supprimee;
325: position_courante < (*s_etat_processus).nombre_variables;
326: position_courante++)
327: {
328: (*s_etat_processus).s_liste_variables[position_courante] =
329: (*s_etat_processus).s_liste_variables
330: [position_courante + 1];
331: }
332:
333: erreur = d_absence_erreur;
334: }
335: else
336: {
337: erreur = d_erreur;
338: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
339: }
340:
341: return erreur;
342: }
343:
344:
345: /*
346: ================================================================================
347: Procédure de recherche d'une variable par son nom dans la base
348: ================================================================================
349: Entrée :
350: --------------------------------------------------------------------------------
351: Sortie :
352: --------------------------------------------------------------------------------
353: Effets de bord : néant
354: ================================================================================
355: */
356:
357: logical1
358: recherche_variable(struct_processus *s_etat_processus,
359: unsigned char *nom_variable)
360: {
361: logical1 existence_variable;
362:
363: long difference;
364: long difference_inferieure;
365: long difference_superieure;
366:
367: struct_liste_pile_systeme *l_element_courant;
368:
369: unsigned long borne_inferieure;
370: unsigned long borne_superieure;
371: unsigned long moyenne;
372: unsigned long niveau_appel;
373: unsigned long nombre_iterations_maximal;
374: unsigned long ordre_iteration;
375:
376: if ((*s_etat_processus).nombre_variables == 0)
377: {
378: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
379: return d_faux;
380: }
381:
382: ordre_iteration = 0;
383: nombre_iterations_maximal = ((unsigned long)
384: (log((*s_etat_processus).nombre_variables) / log(2))) + 2;
385:
386: borne_inferieure = 0;
387: borne_superieure = (*s_etat_processus).nombre_variables - 1;
388:
389: do
390: {
391: moyenne = (borne_inferieure + borne_superieure) / 2;
392: ordre_iteration++;
393:
394: if (((borne_inferieure + borne_superieure) % 2) == 0)
395: {
396: difference = strcmp(nom_variable,
397: ((*s_etat_processus).s_liste_variables)[moyenne].nom);
398:
399: if (difference != 0)
400: {
401: if (difference > 0)
402: {
403: borne_inferieure = moyenne;
404: }
405: else
406: {
407: borne_superieure = moyenne;
408: }
409: }
410: }
411: else
412: {
413: difference_inferieure = strcmp(nom_variable,
414: ((*s_etat_processus).s_liste_variables)[moyenne].nom);
415: difference_superieure = strcmp(nom_variable,
416: ((*s_etat_processus).s_liste_variables)[moyenne + 1].nom);
417:
418: if (difference_inferieure == 0)
419: {
420: difference = 0;
421: }
422: else if (difference_superieure == 0)
423: {
424: difference = 0;
425: moyenne++;
426: }
427: else
428: {
429: difference = difference_inferieure;
430:
431: if (difference > 0)
432: {
433: borne_inferieure = moyenne;
434: }
435: else
436: {
437: borne_superieure = moyenne;
438: }
439: }
440: }
441: } while((difference != 0) &&
442: (ordre_iteration <= nombre_iterations_maximal));
443:
444: if (ordre_iteration > nombre_iterations_maximal)
445: {
446: existence_variable = d_faux;
447: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
448: }
449: else
450: {
451: if ((moyenne + 1) < (*s_etat_processus).nombre_variables)
452: {
453: while(strcmp(((*s_etat_processus).s_liste_variables)
454: [moyenne + 1].nom, nom_variable) == 0)
455: {
456: moyenne++;
457:
458: if ((moyenne + 1) >= (*s_etat_processus).nombre_variables)
459: {
460: break;
461: }
462: }
463: }
464:
465: (*s_etat_processus).position_variable_courante = moyenne;
466:
467: if ((*s_etat_processus).s_liste_variables[(*s_etat_processus)
468: .position_variable_courante].niveau > 1)
469: {
470: // La variable trouvée est une variable locale.
471: // On vérifie qu'elle est accessible à la définition
472: // courante.
473:
474: niveau_appel = (*s_etat_processus).niveau_courant;
475: l_element_courant = (*s_etat_processus).l_base_pile_systeme;
476:
477: if (l_element_courant == NULL)
478: {
479: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
480: existence_variable = d_faux;
481:
482: return existence_variable;
483: }
484:
485: while((*l_element_courant).retour_definition != 'Y')
486: {
487: l_element_courant = (*l_element_courant).suivant;
488:
489: if (l_element_courant == NULL)
490: {
491: (*s_etat_processus).erreur_systeme = d_es_pile_vide;
492: existence_variable = d_faux;
493:
494: return existence_variable;
495: }
496: }
497:
498: niveau_appel = (*l_element_courant).niveau_courant;
499:
500: if (niveau_appel < (*s_etat_processus).s_liste_variables
501: [(*s_etat_processus).position_variable_courante].niveau)
502: {
503: existence_variable = d_vrai;
504: }
505: else
506: {
507: existence_variable = d_faux;
508:
509: // La variable locale n'est pas accessible. On regarde si par
510: // hasard il existe une variable globale.
511:
512: while((*s_etat_processus).position_variable_courante != 0)
513: {
514: if (strcmp(((*s_etat_processus).s_liste_variables)
515: [(*s_etat_processus).position_variable_courante - 1] .nom, nom_variable) == 0)
516: {
517: (*s_etat_processus).position_variable_courante--;
518: }
519: else
520: {
521: if ((*s_etat_processus).s_liste_variables
522: [(*s_etat_processus).position_variable_courante]
523: .niveau <= 1)
524: {
525: existence_variable = d_vrai;
526: }
527:
528: break;
529: }
530: }
531:
532: if ((strcmp(((*s_etat_processus).s_liste_variables)
533: [(*s_etat_processus).position_variable_courante].nom,
534: nom_variable) == 0) && ((*s_etat_processus)
535: .s_liste_variables[(*s_etat_processus)
536: .position_variable_courante].niveau <= 1))
537: {
538: existence_variable = d_vrai;
539: }
540: }
541: }
542: else
543: {
544: // La variable trouvée est soit un pointeur sur une définition
545: // (niveau 0), soit une variable globale (niveau 1).
546:
547: existence_variable = d_vrai;
548: }
549: }
550:
551: return existence_variable;
552: }
553:
554:
555: /*
556: ================================================================================
557: Procédure de retrait des variables de niveau strictement supérieur au
558: niveau courant
559: ================================================================================
560: Entrée :
561: --------------------------------------------------------------------------------
562: Sortie :
563: --------------------------------------------------------------------------------
564: Effets de bord : néant
565: ================================================================================
566: */
567:
568: logical1
569: retrait_variable_par_niveau(struct_processus *s_etat_processus)
570: {
571: unsigned long i;
572: unsigned long j;
573:
574: struct_variable *tampon;
575:
576: for(j = 0, i = 0; i < (*s_etat_processus).nombre_variables; i++)
577: {
578: if ((*s_etat_processus).s_liste_variables[i].niveau <=
579: (*s_etat_processus).niveau_courant)
580: {
581: (*s_etat_processus).s_liste_variables[j++] =
582: (*s_etat_processus).s_liste_variables[i];
583: }
584: else
585: {
586: if ((*s_etat_processus).s_liste_variables[i].origine == 'P')
587: {
588: if ((*s_etat_processus).s_liste_variables[i]
589: .variable_statique.adresse != 0)
590: {
591: /*
592: * Gestion des variables statiques
593: */
594:
595: if (recherche_variable_statique(s_etat_processus,
596: (*s_etat_processus).s_liste_variables[i]
597: .nom, (*s_etat_processus).s_liste_variables
598: [i].variable_statique, ((*s_etat_processus)
599: .mode_execution_programme
600: == 'Y') ? 'P' : 'E') == d_vrai)
601: {
602: (*s_etat_processus).s_liste_variables_statiques
603: [(*s_etat_processus)
604: .position_variable_statique_courante]
605: .objet = (*s_etat_processus)
606: .s_liste_variables[i].objet;
607: }
608: else
609: {
610: (*s_etat_processus).erreur_systeme =
611: d_es_variable_introuvable;
612: }
613:
614: (*s_etat_processus).s_liste_variables[i].objet = NULL;
615: }
616: }
617: else
618: {
619: if ((*s_etat_processus).s_liste_variables[i]
620: .variable_statique.pointeur != NULL)
621: {
622: /*
623: * Gestion des variables statiques
624: */
625:
626: if (recherche_variable_statique(s_etat_processus,
627: (*s_etat_processus).s_liste_variables[i]
628: .nom, (*s_etat_processus).s_liste_variables[i]
629: .variable_statique, ((*s_etat_processus)
630: .mode_execution_programme
631: == 'Y') ? 'P' : 'E') == d_vrai)
632: {
633: (*s_etat_processus).s_liste_variables_statiques
634: [(*s_etat_processus)
635: .position_variable_statique_courante]
636: .objet = (*s_etat_processus)
637: .s_liste_variables[i].objet;
638: }
639: else
640: {
641: (*s_etat_processus).erreur_systeme =
642: d_es_variable_introuvable;
643: }
644:
645: (*s_etat_processus).s_liste_variables[i].objet = NULL;
646: }
647: }
648:
649: free((*s_etat_processus).s_liste_variables[i].nom);
650: liberation(s_etat_processus,
651: (*s_etat_processus).s_liste_variables[i].objet);
652: }
653: }
654:
655: (*s_etat_processus).nombre_variables = j;
656:
657: if ((*s_etat_processus).nombre_variables <
658: ((*s_etat_processus).nombre_variables_allouees / 2))
659: {
660: (*s_etat_processus).nombre_variables_allouees /= 2;
661:
662: if ((tampon = realloc((*s_etat_processus).s_liste_variables,
663: (*s_etat_processus).nombre_variables_allouees *
664: sizeof(struct_variable))) == NULL)
665: {
666: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
667: return(d_erreur);
668: }
669:
670: (*s_etat_processus).s_liste_variables = tampon;
671: }
672:
673: return(d_absence_erreur);
674: }
675:
676: // vim: ts=4