File:
[local] /
rpl /
modules /
sets /
types.rplc
Revision
1.4:
download - view:
text,
annotated -
select for diffs -
revision graph
Sun Jul 2 22:28:20 2017 UTC (6 years, 11 months ago) by
bertrand
Branches:
MAIN
CVS tags:
HEAD
Dernière série de patches pour gérer les types externes dans les
bibliothèques. Voir pour cela modules/sets. Fonctionne.
Attention, ne permet pas encore de compiler un code utilisant des types
externes (la compilation se fait avant l'exécution de l'instruction USE).
1: #define TYPE_DECLARATION
2: #include "src/rplexternals.h"
3: #include "sets.h"
4:
5: // Les objets de type ensemble sont délimités par ([ ]) et ne contiennent
6: // que des entiers.
7:
8: // Attention : ces fonctions sont à écrire directement en C et non
9: // en RPL/C car elles interviennent dans le noyau RPL/2.
10:
11: /*
12: ================================================================================
13: Fonction permettant d'extraire un objet d'une suite de caractères
14:
15: Cette fonction est utilisée par la routine recherche_instruction_suivante()
16: du RPL/2.
17: ================================================================================
18: */
19:
20: declareTypeExtension(parse)
21: if ((*rptr) == '(')
22: {
23: rptr++;
24:
25: if ((*rptr) == '[')
26: {
27: rptr++;
28: while((*rptr) != 0)
29: {
30: switch (*rptr)
31: {
32: case '0':
33: case '1':
34: case '2':
35: case '3':
36: case '4':
37: case '5':
38: case '6':
39: case '7':
40: case '8':
41: case '9':
42: case ' ':
43: {
44: break;
45: }
46:
47: case ']':
48: {
49: rptr++;
50:
51: if ((*rptr) == ')')
52: {
53: rptr++;
54: return(sizeOfParse);
55: }
56: else
57: {
58: parseError;
59: }
60: }
61:
62: default:
63: {
64: parseError;
65: }
66: }
67:
68: rptr++;
69: }
70: }
71: }
72: endTypeExtension
73:
74:
75: /*
76: ================================================================================
77: La fonction declareTypeExtension(new) est utilisée par la fonction
78: recherche_type() du RPL/2. Elle se charge d'allouer et d'initialiser
79: le champ objet de la struct_objet allouée par recherche_type().
80: ================================================================================
81: */
82:
83: static int
84: fonction_ordre(const void *a, const void *b)
85: {
86: if ((*((integer8 *) a)) < (*((integer8 *) b)))
87: {
88: return(-1);
89: }
90: if ((*((integer8 *) a)) > (*((integer8 *) b)))
91: {
92: return(1);
93: }
94:
95: return(0);
96: }
97:
98: declareTypeExtension(new)
99: // Si le premier caractère de la chaîne est '(' et que le dernier est ')',
100: // on les retire.
101:
102: char *tmp;
103:
104: integer8 current_value;
105: integer8 i;
106: integer8 j;
107: integer8 nb_elements;
108: integer8 *vecteur;
109:
110: if (((*iptr) == '(') && ((*(iptr + strlen(iptr) - 1)) == ')'))
111: {
112: if ((tmp = malloc((strlen(iptr) + 1) * sizeof(unsigned char)))
113: == NULL)
114: {
115: typeSystemError;
116: }
117:
118: // Sauvegarde de l'instruction courante.
119: strcpy(tmp, iptr);
120:
121: // Création d'une nouvelle instruction courante amputée de ses premier
122: // et dernier caractères.
123: memmove(iptr, iptr + 1, strlen(iptr) - 2);
124: *(iptr + strlen(iptr) - 2) = 0;
125:
126: searchType(strcpy(iptr, tmp), free(tmp));
127:
128: // Restauration de l'instruction courante
129: strcpy(iptr, tmp);
130: free(tmp);
131:
132: // On doit avoir un vecteur d'entiers au niveau 1 de la pile.
133: // Si ce n'est pas le cas, il y a une erreur.
134:
135: if ((*(*(*s_etat_processus).l_base_pile).donnee).type != VIN)
136: {
137: typeError;
138: }
139:
140: nb_elements = (*((struct_vecteur *) (*(*(*s_etat_processus)
141: .l_base_pile).donnee).objet)).taille;
142:
143: if (nb_elements > 0)
144: {
145: if ((vecteur = malloc(nb_elements * sizeof(integer8))) == NULL)
146: {
147: typeSystemError;
148: }
149:
150: for(i = 0; i < nb_elements; i++)
151: {
152: vecteur[i] = ((integer8 *) (*((struct_vecteur *)
153: (*(*(*s_etat_processus)
154: .l_base_pile).donnee).objet)).tableau)[i];
155: }
156:
157: qsort(vecteur, nb_elements, sizeof(integer8), fonction_ordre);
158:
159: // Élimination des doublons
160:
161: current_value = vecteur[0];
162:
163: for(i = 1, j = 1; i < nb_elements; i++)
164: {
165: if (vecteur[i] != current_value)
166: {
167: vecteur[j++] = vecteur[i];
168: current_value = vecteur[i];
169: }
170: }
171:
172: nb_elements = j;
173:
174: if ((vecteur = realloc(vecteur, nb_elements * sizeof(integer8)))
175: == NULL)
176: {
177: typeSystemError;
178: }
179: }
180: else
181: {
182: // cas de l'ensemble vide
183: if ((vecteur = malloc(0)) == NULL)
184: {
185: typeSystemError;
186: }
187: }
188:
189: if (((*arg) = malloc(sizeof(set_t))) == NULL)
190: {
191: typeSystemError;
192: }
193:
194: (**((set_t **) arg)).size = nb_elements;
195: (**((set_t **) arg)).values = vecteur;
196:
197: instruction_drop(s_etat_processus);
198: typeFound(ISET);
199: }
200:
201: typeError;
202: endTypeExtension
203:
204:
205: /*
206: ================================================================================
207: Fonction de duplication d'un objet.
208:
209: Cet objet doit être alloué puis copié.
210: ================================================================================
211: */
212:
213: declareTypeExtension(dup)
214: integer8 i;
215:
216: struct_objet *n_arg;
217:
218: if ((n_arg = allocation(s_etat_processus, EXT)) == NULL)
219: {
220: typeSystemError;
221: }
222:
223: if (((*n_arg).objet = malloc(sizeof(set_t))) == NULL)
224: {
225: typeSystemError;
226: }
227:
228: (*((set_t *) ((*n_arg).objet))).size = (*((set_t *) (**((struct_objet **)
229: arg)).objet)).size;
230: (*n_arg).descripteur_bibliotheque =
231: (**((struct_objet **) arg)).descripteur_bibliotheque;
232: (*n_arg).extension_type =
233: (**((struct_objet **) arg)).extension_type;
234:
235: for(i = 0; i < (*((set_t *) (**((struct_objet **) arg)).objet)).size; i++)
236: {
237: (*((set_t *) ((*n_arg).objet))).values[i] =
238: (*((set_t *) (**((struct_objet **) arg)).objet)).values[i];
239: }
240:
241: arg = (void **) &n_arg;
242: typeSuccess;
243: endTypeExtension
244:
245:
246: /*
247: ================================================================================
248: Fonction de libération d'un objet. À l'instar de la fonction new qui n'alloue
249: pas la struct_objet, la fonction drop ne doit pas la libérer.
250: ================================================================================
251: */
252:
253: declareTypeExtension(drop)
254: free((*((set_t *) (**((struct_objet **) arg)).objet)).values);
255: free((**((struct_objet **) arg)).objet);
256: typeSuccess;
257: endTypeExtension
258:
259:
260: /*
261: ================================================================================
262: Fonction créant une chaîne de caractère depuis l'objet pour affichage
263: ================================================================================
264: */
265:
266: declareTypeExtension(disp)
267: int i;
268:
269: string e;
270: string s;
271: string t;
272:
273: if ((s = malloc(3 * sizeof(unsigned char))) == NULL)
274: {
275: typeSystemError;
276: }
277:
278: strcpy(s, "([");
279:
280: for(i = 0; i < (*((set_t *) (*((struct_objet *) (*arg))).objet)).size; i++)
281: {
282: if ((e = (string) integerFormat(&((*((set_t *)
283: (*((struct_objet *) (*arg))).objet)).values[i]))) == NULL)
284: {
285: typeSystemError;
286: }
287:
288: t = s;
289:
290: if ((s = malloc((strlen(t) + strlen(e) + 2) * sizeof(unsigned char)))
291: == NULL)
292: {
293: typeSystemError;
294: }
295:
296: strcpy(s, t);
297: free(t);
298: strcat(s, " ");
299: strcat(s, e);
300: free(e);
301: }
302:
303: t = s;
304:
305: if ((s = malloc((strlen(t) + 4) * sizeof(unsigned char))) == NULL)
306: {
307: typeSystemError;
308: }
309:
310: strcpy(s, t);
311: free(t);
312: strcat(s, " ])");
313:
314: (*arg) = s;
315: typeSuccess;
316: endTypeExtension
317:
318: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>