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