File:
[local] /
rpl /
src /
gestion_variables_statiques.c
Revision
1.21:
download - view:
text,
annotated -
select for diffs -
revision graph
Tue Jun 21 15:26:29 2011 UTC (13 years, 3 months ago) by
bertrand
Branches:
MAIN
CVS tags:
HEAD
Correction d'une réinitialisation sauvage de la pile des variables par niveau
dans la copie de la structure de description du processus. Cela corrige
la fonction SPAWN qui échouait sur un segmentation fault car la pile des
variables par niveau était vide alors même que l'arbre des variables contenait
bien les variables. Passage à la prerelease 2.
1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.0.prerelease.2
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: Routine de création d'une nouvelle variable statique
29: ================================================================================
30: Entrée :
31: --------------------------------------------------------------------------------
32: Sortie :
33: --------------------------------------------------------------------------------
34: Effets de bords : néant
35: ================================================================================
36: */
37:
38: logical1
39: creation_variable_statique(struct_processus *s_etat_processus,
40: struct_variable_statique *s_variable)
41: {
42: struct_variable_statique *s_nouvelle_base;
43:
44: long i;
45:
46: (*s_etat_processus).nombre_variables_statiques++;
47:
48: if ((*s_etat_processus).nombre_variables_statiques > (*s_etat_processus)
49: .nombre_variables_statiques_allouees)
50: {
51: // La nouvelle variable statique ne tient pas dans la table courante.
52: // Il convient donc d'en augmenter la taille.
53:
54: if ((*s_etat_processus).nombre_variables_statiques_allouees == 0)
55: {
56: (*s_etat_processus).nombre_variables_statiques_allouees =
57: (*s_etat_processus).nombre_variables_statiques;
58: }
59: else
60: {
61: while((*s_etat_processus).nombre_variables_statiques >
62: (*s_etat_processus).nombre_variables_statiques_allouees)
63: {
64: (*s_etat_processus).nombre_variables_statiques_allouees *= 2;
65: }
66: }
67:
68: if ((s_nouvelle_base = realloc((*s_etat_processus)
69: .s_liste_variables_statiques, (*s_etat_processus)
70: .nombre_variables_statiques_allouees *
71: sizeof(struct_variable_statique))) == NULL)
72: {
73: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
74: (*s_etat_processus).nombre_variables_statiques--;
75: return(d_erreur);
76: }
77:
78: (*s_etat_processus).s_liste_variables_statiques = s_nouvelle_base;
79: }
80:
81: /*
82: * Positionnement de la variable statique au bon endroit
83: */
84:
85: // Nous avons (*s_etat_processus).nombre_variables_statiques - 1 variables
86: // dans la table qui sera balayée de la fin vers le début.
87:
88: if ((*s_etat_processus).nombre_variables_statiques == 1)
89: {
90: (*s_etat_processus).s_liste_variables_statiques[0] = (*s_variable);
91: }
92: else
93: {
94: for(i = (*s_etat_processus).nombre_variables_statiques - 2; i >= 0; i--)
95: {
96: if (strcmp((*s_variable).nom,
97: (*s_etat_processus).s_liste_variables_statiques[i].nom) < 0)
98: {
99: (*s_etat_processus).s_liste_variables_statiques[i + 1] =
100: (*s_etat_processus).s_liste_variables_statiques[i];
101: }
102: else
103: {
104: break;
105: }
106: }
107:
108: (*s_etat_processus).s_liste_variables_statiques[i + 1] = (*s_variable);
109: }
110:
111: return d_absence_erreur;
112: }
113:
114:
115: /*
116: ================================================================================
117: Procédure de retrait d'une variable statique de la base
118: ================================================================================
119: Entrée :
120: --------------------------------------------------------------------------------
121: Sortie :
122: --------------------------------------------------------------------------------
123: Effets de bord : néant
124: ================================================================================
125: */
126:
127: logical1
128: retrait_variable_statique(struct_processus *s_etat_processus,
129: unsigned char *nom_variable, union_position_variable position)
130: {
131: struct_variable_statique *s_nouvelle_base;
132:
133: logical1 erreur;
134:
135: unsigned long position_courante;
136: unsigned long position_supprimee;
137:
138: if (recherche_variable_statique(s_etat_processus, nom_variable,
139: position, ((*s_etat_processus).mode_execution_programme == 'Y')
140: ? 'P' : 'E') == d_vrai)
141: {
142: if ((*s_etat_processus).nombre_variables_statiques <
143: ((*s_etat_processus).nombre_variables_statiques_allouees / 2))
144: {
145: (*s_etat_processus).nombre_variables_statiques_allouees /= 2;
146:
147: if ((s_nouvelle_base =
148: realloc((*s_etat_processus).s_liste_variables_statiques,
149: (*s_etat_processus).nombre_variables_statiques_allouees *
150: sizeof(struct_variable_statique))) == NULL)
151: {
152: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
153: return(d_erreur);
154: }
155:
156: (*s_etat_processus).s_liste_variables_statiques = s_nouvelle_base;
157: }
158:
159: position_supprimee = (*s_etat_processus)
160: .position_variable_statique_courante;
161:
162: liberation(s_etat_processus, (*s_etat_processus)
163: .s_liste_variables_statiques[position_supprimee].objet);
164: free((*s_etat_processus).s_liste_variables_statiques
165: [position_supprimee].nom);
166:
167: (*s_etat_processus).nombre_variables_statiques--;
168:
169: for(position_courante = position_supprimee; position_courante <
170: (*s_etat_processus).nombre_variables_statiques;
171: position_courante++)
172: {
173: (*s_etat_processus).s_liste_variables_statiques[position_courante]
174: = (*s_etat_processus).s_liste_variables_statiques
175: [position_courante + 1];
176: }
177:
178: erreur = d_absence_erreur;
179: }
180: else
181: {
182: erreur = d_erreur;
183: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
184: }
185:
186: return erreur;
187: }
188:
189:
190: /*
191: ================================================================================
192: Procédure de recherche d'une variable statique par son nom dans la base
193: ================================================================================
194: Entrée :
195: --------------------------------------------------------------------------------
196: Sortie :
197: --------------------------------------------------------------------------------
198: Effets de bord : néant
199: ================================================================================
200: */
201:
202: logical1
203: recherche_variable_statique(struct_processus *s_etat_processus,
204: unsigned char *nom_variable, union_position_variable position,
205: unsigned char origine)
206: {
207: logical1 existence_variable;
208:
209: long difference;
210: long difference_inferieure;
211: long difference_superieure;
212:
213: unsigned long borne_inferieure;
214: unsigned long borne_superieure;
215: unsigned long moyenne;
216: unsigned long nombre_iterations_maximal;
217: unsigned long ordre_iteration;
218:
219: if ((*s_etat_processus).nombre_variables_statiques == 0)
220: {
221: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
222: return d_faux;
223: }
224:
225: ordre_iteration = 0;
226: nombre_iterations_maximal = ((unsigned long)
227: (log((*s_etat_processus).nombre_variables_statiques) / log(2))) + 2;
228:
229: borne_inferieure = 0;
230: borne_superieure = (*s_etat_processus).nombre_variables_statiques - 1;
231:
232: do
233: {
234: moyenne = (borne_inferieure + borne_superieure) / 2;
235: ordre_iteration++;
236:
237: if ((2 * ((unsigned long) ((borne_inferieure + borne_superieure) / 2)))
238: == (borne_inferieure + borne_superieure))
239: {
240: difference = strcmp(nom_variable,
241: ((*s_etat_processus).s_liste_variables_statiques)
242: [moyenne].nom);
243:
244: if (difference != 0)
245: {
246: if (difference > 0)
247: {
248: borne_inferieure = moyenne;
249: }
250: else
251: {
252: borne_superieure = moyenne;
253: }
254: }
255: }
256: else
257: {
258: difference_inferieure = strcmp(nom_variable,
259: ((*s_etat_processus).s_liste_variables_statiques)
260: [moyenne].nom);
261: difference_superieure = strcmp(nom_variable,
262: ((*s_etat_processus).s_liste_variables_statiques)
263: [moyenne + 1].nom);
264:
265: if (difference_inferieure == 0)
266: {
267: difference = 0;
268: }
269: else if (difference_superieure == 0)
270: {
271: difference = 0;
272: moyenne++;
273: }
274: else
275: {
276: difference = difference_inferieure;
277:
278: if (difference > 0)
279: {
280: borne_inferieure = moyenne;
281: }
282: else
283: {
284: borne_superieure = moyenne;
285: }
286: }
287: }
288: } while((difference != 0) &&
289: (ordre_iteration <= nombre_iterations_maximal));
290:
291: if (ordre_iteration > nombre_iterations_maximal)
292: {
293: existence_variable = d_faux;
294: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
295: }
296: else
297: {
298: // Reste à rechercher la variable déclarée à la position 'position'...
299:
300: if (((*s_etat_processus).s_liste_variables_statiques)[moyenne]
301: .origine == 'P')
302: {
303: if ((((*s_etat_processus).s_liste_variables_statiques)[moyenne]
304: .variable_statique.adresse == position.adresse) &&
305: (((*s_etat_processus).s_liste_variables_statiques)[moyenne]
306: .origine == origine))
307: {
308: existence_variable = d_vrai;
309: }
310: else
311: {
312: existence_variable = d_faux;
313: }
314: }
315: else
316: {
317: if ((((*s_etat_processus).s_liste_variables_statiques)[moyenne]
318: .variable_statique.pointeur == position.pointeur) &&
319: (((*s_etat_processus).s_liste_variables_statiques)[moyenne]
320: .origine == origine))
321: {
322: existence_variable = d_vrai;
323: }
324: else
325: {
326: existence_variable = d_faux;
327: }
328: }
329:
330: if (existence_variable == d_faux)
331: {
332: // On rembobine.
333:
334: if (moyenne > 0)
335: {
336: while(strcmp(nom_variable, ((*s_etat_processus)
337: .s_liste_variables_statiques)[moyenne - 1].nom) == 0)
338: {
339: moyenne--;
340:
341: if (moyenne == 0)
342: {
343: break;
344: }
345: }
346: }
347:
348: // Un petit test pour voir si le premier élément du tableau
349: // peut correspondre au critère de recherche.
350:
351: existence_variable = d_faux;
352:
353: if (strcmp(((*s_etat_processus).s_liste_variables_statiques)
354: [moyenne].nom, nom_variable) == 0)
355: {
356: if (((*s_etat_processus).s_liste_variables_statiques)
357: [moyenne].origine == 'P')
358: {
359: if ((((*s_etat_processus).s_liste_variables_statiques)
360: [moyenne].variable_statique.adresse
361: == position.adresse) &&
362: (((*s_etat_processus).s_liste_variables_statiques)
363: [moyenne].origine == origine))
364: {
365: existence_variable = d_vrai;
366: }
367: }
368: else
369: {
370: if ((((*s_etat_processus).s_liste_variables_statiques)
371: [moyenne].variable_statique.pointeur
372: == position.pointeur) &&
373: (((*s_etat_processus).s_liste_variables_statiques)
374: [moyenne].origine == origine))
375: {
376: existence_variable = d_vrai;
377: }
378: }
379: }
380:
381: // Puis on balaye dans le sens croissant.
382:
383: if (((moyenne + 1) < (*s_etat_processus)
384: .nombre_variables_statiques) &&
385: (existence_variable == d_faux))
386: {
387: while(strcmp(((*s_etat_processus)
388: .s_liste_variables_statiques)[moyenne + 1].nom,
389: nom_variable) == 0)
390: {
391: moyenne++;
392:
393: if (((*s_etat_processus).s_liste_variables_statiques)
394: [moyenne].origine == 'P')
395: {
396: if ((((*s_etat_processus).s_liste_variables_statiques)
397: [moyenne].variable_statique.adresse ==
398: position.adresse) && (((*s_etat_processus)
399: .s_liste_variables_statiques)
400: [moyenne].origine == origine))
401: {
402: existence_variable = d_vrai;
403: break;
404: }
405: }
406: else
407: {
408: if ((((*s_etat_processus).s_liste_variables_statiques)
409: [moyenne].variable_statique.pointeur ==
410: position.pointeur) && (((*s_etat_processus)
411: .s_liste_variables_statiques)
412: [moyenne].origine == origine))
413: {
414: existence_variable = d_vrai;
415: break;
416: }
417: }
418:
419: if ((moyenne + 1) >= (*s_etat_processus)
420: .nombre_variables_statiques)
421: {
422: break;
423: }
424: }
425: }
426: }
427:
428: (*s_etat_processus).position_variable_statique_courante = moyenne;
429: }
430:
431: return existence_variable;
432: }
433:
434: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>