1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.11
4: Copyright (C) 1989-2012 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: Boucle principale de l'interprète RPL/2
29: ================================================================================
30: Entrées : structure sur l'état du processus
31: --------------------------------------------------------------------------------
32: Sorties : néant
33: --------------------------------------------------------------------------------
34: Effets de bord : néant
35: ================================================================================
36: */
37:
38: logical1
39: sequenceur(struct_processus *s_etat_processus)
40: {
41: struct_liste_chainee *l_element_courant;
42:
43: struct_objet *s_objet;
44: struct_objet *s_objet_evaluation;
45: struct_objet *s_sous_objet;
46:
47: logical1 drapeau_appel_definition;
48: logical1 drapeau_fin;
49: logical1 drapeau_then;
50: logical1 erreur;
51: logical1 presence_compteur;
52:
53: static logical1 completion_valide = d_faux;
54:
55: struct sigaction action;
56: struct sigaction action_defaut;
57: struct sigaction action_defaut2;
58:
59: unsigned char *instruction_majuscule;
60: unsigned char *ligne;
61: unsigned char *message;
62: unsigned char *registre;
63: unsigned char *tampon;
64: unsigned char tampon_retour;
65: unsigned char *t_ligne;
66:
67: unsigned long niveau;
68: unsigned long position_courante;
69:
70: Keymap ancien_keymap;
71: Keymap nouveau_keymap;
72:
73: (*s_etat_processus).retour_routine_evaluation = 'N';
74:
75: if ((*s_etat_processus).debug == d_vrai)
76: if (((*s_etat_processus).type_debug &
77: d_debug_appels_fonctions) != 0)
78: {
79: if ((*s_etat_processus).niveau_recursivite != 0)
80: {
81: if ((*s_etat_processus).langue == 'F')
82: {
83: printf("[%d] Exécution récursive de niveau %lu\n",
84: (int) getpid(), (*s_etat_processus).niveau_recursivite);
85: }
86: else
87: {
88: printf("[%d] %lu level recursive execution\n",
89: (int) getpid(), (*s_etat_processus).niveau_recursivite);
90: }
91: }
92: else
93: {
94: if ((*s_etat_processus).langue == 'F')
95: {
96: printf("[%d] Exécution\n", (int) getpid());
97: }
98: else
99: {
100: printf("[%d] Execution\n", (int) getpid());
101: }
102: }
103:
104: fflush(stdout);
105: }
106:
107: /*
108: --------------------------------------------------------------------------------
109: Boucle de l'interprète RPL/2
110: On boucle tant qu'on n'a pas une bonne raison de sortir...
111: --------------------------------------------------------------------------------
112: */
113:
114: do
115: {
116: drapeau_appel_definition = d_faux;
117:
118: /*
119: --------------------------------------------------------------------------------
120: Recherche de l'instruction suivante dans les définitions chaînées
121: --------------------------------------------------------------------------------
122: */
123:
124: if ((erreur = recherche_instruction_suivante(s_etat_processus))
125: == d_erreur)
126: {
127: return(d_erreur);
128: }
129:
130: if (((*s_etat_processus).debug_programme == d_vrai) &&
131: ((*s_etat_processus).niveau_recursivite == 0))
132: {
133: /*
134: * Traitement de la commande HALT (debug)
135: */
136:
137: action.sa_handler = SIG_IGN;
138: action.sa_flags = SA_NODEFER | SA_ONSTACK;
139:
140: (*s_etat_processus).execution_pas_suivant = d_faux;
141: (*s_etat_processus).traitement_instruction_halt = d_vrai;
142:
143: if (completion_valide == d_faux)
144: {
145: initialisation_completion();
146: completion_valide = d_vrai;
147: }
148:
149: while((*s_etat_processus).execution_pas_suivant == d_faux)
150: {
151: if ((*s_etat_processus).hauteur_pile_operationnelle != 0)
152: {
153: fprintf(stdout, "\n");
154: }
155:
156: affichage_pile(s_etat_processus, (*s_etat_processus)
157: .l_base_pile, 1);
158:
159: if ((*s_etat_processus).mode_interactif == 'N')
160: {
161: printf("[%d] Instruction : %s\n", (int) getpid(),
162: (*s_etat_processus).instruction_courante);
163: fflush(stdout);
164: }
165:
166: if (sigaction(SIGINT, &action, &action_defaut) != 0)
167: {
168: (*s_etat_processus).erreur_systeme = d_es_signal;
169: return(d_erreur);
170: }
171:
172: if (sigaction(SIGTSTP, &action, &action_defaut2) != 0)
173: {
174: (*s_etat_processus).erreur_systeme = d_es_signal;
175: return(d_erreur);
176: }
177:
178: (*s_etat_processus).var_volatile_requete_arret = 0;
179: (*s_etat_processus).var_volatile_requete_arret2 = 0;
180:
181: flockfile(stdin);
182: flockfile(stdout);
183:
184: ancien_keymap = rl_get_keymap();
185: nouveau_keymap = rl_copy_keymap(ancien_keymap);
186: rl_set_keymap(nouveau_keymap);
187:
188: rl_bind_key(NEWLINE, readline_analyse_syntaxique);
189: rl_bind_key(RETURN, readline_analyse_syntaxique);
190: rl_bind_key(CTRL('g'), readline_effacement);
191: rl_done = 0;
192:
193: ligne = readline("RPL/2> ");
194:
195: rl_set_keymap(ancien_keymap);
196: rl_free(nouveau_keymap);
197:
198: funlockfile(stdin);
199: funlockfile(stdout);
200:
201: if ((*s_etat_processus).var_volatile_requete_arret != 0)
202: {
203: (*s_etat_processus).requete_arret = 'Y';
204: break;
205: }
206:
207: if (ligne != NULL)
208: {
209: if ((t_ligne = transliteration(s_etat_processus, ligne,
210: (*s_etat_processus).localisation, d_locale))
211: == NULL)
212: {
213: free((*s_etat_processus).instruction_courante);
214: return(d_erreur);
215: }
216:
217: free(ligne);
218: ligne = t_ligne;
219:
220: if ((ligne = compactage(ligne)) == NULL)
221: {
222: (*s_etat_processus).erreur_systeme =
223: d_es_allocation_memoire;
224: return(d_erreur);
225: }
226: }
227:
228: if (sigaction(SIGINT, &action_defaut, NULL) != 0)
229: {
230: (*s_etat_processus).erreur_systeme = d_es_signal;
231: return(d_erreur);
232: }
233:
234: if (sigaction(SIGTSTP, &action_defaut2, NULL) != 0)
235: {
236: (*s_etat_processus).erreur_systeme = d_es_signal;
237: return(d_erreur);
238: }
239:
240: if (ligne == NULL)
241: {
242: if ((ligne = (unsigned char *) malloc(6 *
243: sizeof(unsigned char))) == NULL)
244: {
245: (*s_etat_processus).erreur_systeme =
246: d_es_allocation_memoire;
247: return(d_erreur);
248: }
249:
250: sprintf(ligne, "abort");
251: fprintf(stdout, "%s\n", ligne);
252: }
253: else if (((*ligne) == d_code_fin_chaine) &&
254: ((*s_etat_processus).l_base_pile != NULL))
255: {
256: free(ligne);
257:
258: if ((ligne = (unsigned char *) malloc(4 *
259: sizeof(unsigned char))) == NULL)
260: {
261: (*s_etat_processus).erreur_systeme =
262: d_es_allocation_memoire;
263: return(d_erreur);
264: }
265:
266: sprintf(ligne, "dup");
267: }
268:
269: add_history(ligne);
270: stifle_history(ds_longueur_historique);
271:
272: position_courante = (*s_etat_processus).position_courante;
273: tampon = (*s_etat_processus).definitions_chainees;
274: registre = (*s_etat_processus).instruction_courante;
275: (*s_etat_processus).definitions_chainees = ligne;
276:
277: if (analyse_syntaxique(s_etat_processus) == d_absence_erreur)
278: {
279: (*s_etat_processus).instruction_courante = registre;
280: (*s_etat_processus).position_courante = position_courante;
281: (*s_etat_processus).definitions_chainees = tampon;
282:
283: if ((tampon = (unsigned char *) malloc((strlen(ligne) + 7) *
284: sizeof(unsigned char))) == NULL)
285: {
286: (*s_etat_processus).erreur_systeme =
287: d_es_allocation_memoire;
288: return(d_erreur);
289: }
290:
291: sprintf(tampon, "<< %s >>", ligne);
292:
293: free(ligne);
294: ligne = tampon;
295:
296: tampon = (*s_etat_processus).instruction_courante;
297: (*s_etat_processus).instruction_courante = ligne;
298:
299: recherche_type(s_etat_processus);
300:
301: (*s_etat_processus).instruction_courante = tampon;
302:
303: if ((((*s_etat_processus).erreur_execution != d_ex) ||
304: ((*s_etat_processus).erreur_systeme != d_es)) &&
305: ((*s_etat_processus).invalidation_message_erreur
306: == d_faux))
307: {
308: if ((*s_etat_processus).erreur_execution != d_ex)
309: {
310: (*s_etat_processus).erreur_scrutation = d_vrai;
311: }
312:
313: if (test_cfsf(s_etat_processus, 51) == d_faux)
314: {
315: printf("%s", ds_beep);
316: }
317:
318: if ((message = messages(s_etat_processus)) == NULL)
319: {
320: free((*s_etat_processus).instruction_courante);
321: return(d_erreur);
322: }
323:
324: printf("%s [%d]\n", message, (int) getpid());
325:
326: free(message);
327:
328: (*s_etat_processus).erreur_execution = d_ex;
329:
330: if ((*s_etat_processus).erreur_systeme != d_es)
331: {
332: return(d_erreur);
333: }
334: }
335: else
336: {
337: tampon_retour = (*(*s_etat_processus)
338: .l_base_pile_systeme).retour_definition;
339: (*(*s_etat_processus).l_base_pile_systeme)
340: .retour_definition = 'Y';
341:
342: if (depilement(s_etat_processus, &((*s_etat_processus)
343: .l_base_pile), &s_objet) == d_erreur)
344: {
345: if (test_cfsf(s_etat_processus, 51) == d_faux)
346: {
347: printf("%s", ds_beep);
348: }
349:
350: if ((*s_etat_processus).langue == 'F')
351: {
352: printf("+++Erreur : Défaut d'argument\n");
353: }
354: else
355: {
356: printf("+++Error : Too few arguments\n");
357: }
358:
359: (*(*s_etat_processus).l_base_pile_systeme)
360: .retour_definition = tampon_retour;
361:
362: fflush(stdout);
363: }
364: else if (evaluation(s_etat_processus, s_objet, 'I') ==
365: d_erreur)
366: {
367: (*(*s_etat_processus).l_base_pile_systeme)
368: .retour_definition = tampon_retour;
369:
370: if ((*s_etat_processus).erreur_systeme != d_es)
371: {
372: if (test_cfsf(s_etat_processus, 51) == d_faux)
373: {
374: printf("%s", ds_beep);
375: }
376:
377: if ((message = messages(s_etat_processus))
378: == NULL)
379: {
380: free((*s_etat_processus)
381: .instruction_courante);
382: return(d_erreur);
383: }
384:
385: printf("%s [%d]\n", message, (int) getpid());
386:
387: free(message);
388: free((*s_etat_processus).instruction_courante);
389: return(d_erreur);
390: }
391: else if ((*s_etat_processus)
392: .invalidation_message_erreur == d_faux)
393: {
394: (*s_etat_processus).erreur_execution =
395: (*s_etat_processus)
396: .derniere_erreur_evaluation;
397:
398: if (test_cfsf(s_etat_processus, 51) == d_faux)
399: {
400: printf("%s", ds_beep);
401: }
402:
403: if ((message = messages(s_etat_processus))
404: == NULL)
405: {
406: free((*s_etat_processus)
407: .instruction_courante);
408: return(d_erreur);
409: }
410:
411: printf("%s [%d]\n", message, (int) getpid());
412: free(message);
413:
414: if (test_cfsf(s_etat_processus, 31) == d_vrai)
415: {
416: l_element_courant = (*s_etat_processus)
417: .l_base_pile_last;
418:
419: while(l_element_courant != NULL)
420: {
421: if ((s_sous_objet = copie_objet(
422: s_etat_processus,
423: (*l_element_courant).donnee,
424: 'P')) == NULL)
425: {
426: (*s_etat_processus).erreur_systeme =
427: d_es_allocation_memoire;
428: return(d_erreur);
429: }
430:
431: if (empilement(s_etat_processus,
432: &((*s_etat_processus)
433: .l_base_pile),
434: s_sous_objet) == d_erreur)
435: {
436: return(d_erreur);
437: }
438:
439: l_element_courant = (*l_element_courant)
440: .suivant;
441: }
442: }
443:
444: (*s_etat_processus).erreur_execution = d_ex;
445: (*s_etat_processus).exception = d_ep;
446: }
447:
448: liberation(s_etat_processus, s_objet);
449: }
450: else
451: {
452: liberation(s_etat_processus, s_objet);
453: }
454:
455: (*(*s_etat_processus).l_base_pile_systeme)
456: .retour_definition = tampon_retour;
457: }
458: }
459: else if ((*s_etat_processus).invalidation_message_erreur
460: == d_faux)
461: {
462: (*s_etat_processus).instruction_courante = registre;
463: (*s_etat_processus).position_courante = position_courante;
464: (*s_etat_processus).definitions_chainees = tampon;
465:
466: if (test_cfsf(s_etat_processus, 51) == d_faux)
467: {
468: printf("%s", ds_beep);
469: }
470:
471: if ((message = messages(s_etat_processus)) == NULL)
472: {
473: free((*s_etat_processus).instruction_courante);
474: free(ligne);
475: return(d_erreur);
476: }
477:
478: free(message);
479:
480: if ((*s_etat_processus).langue == 'F')
481: {
482: printf("+++Erreur : Erreur de syntaxe\n");
483: }
484: else
485: {
486: printf("+++Error : Syntax error\n");
487: }
488:
489: fflush(stdout);
490: }
491:
492: free(ligne);
493: }
494:
495: (*s_etat_processus).traitement_instruction_halt = d_faux;
496: }
497:
498: if ((*s_etat_processus).debug == d_vrai)
499: if (((*s_etat_processus).type_debug &
500: d_debug_fonctions_intrinseques) != 0)
501: {
502: if ((*s_etat_processus).langue == 'F')
503: {
504: printf("[%d] Instruction %s\n",
505: (int) getpid(),
506: (*s_etat_processus).instruction_courante);
507: }
508: else
509: {
510: printf("[%d] %s instruction\n",
511: (int) getpid(),
512: (*s_etat_processus).instruction_courante);
513: }
514:
515: fflush(stdout);
516: }
517:
518: /*
519: --------------------------------------------------------------------------------
520: Dans le cas où une instruction est retournée, celle-ci est évaluée. Dans le
521: cas contraire, l'interprète renvoie un message d'erreur et s'interrompt.
522: --------------------------------------------------------------------------------
523: */
524:
525: if (erreur == d_absence_erreur)
526: {
527:
528: /*
529: --------------------------------------------------------------------------------
530: Scrutation des mots clef du langage RPL/2 et exécution le cas échéant
531: de l'action associée.
532: --------------------------------------------------------------------------------
533: */
534:
535: analyse(s_etat_processus, NULL);
536:
537: if ((*s_etat_processus).traitement_cycle_exit != 'N')
538: {
539: switch((*s_etat_processus).traitement_cycle_exit)
540: {
541: case 'C' :
542: {
543: instruction_cycle(s_etat_processus);
544: break;
545: }
546:
547: case 'E' :
548: {
549: instruction_exit(s_etat_processus);
550: break;
551: }
552: }
553: }
554:
555: if ((*s_etat_processus).instruction_valide == 'N')
556: {
557:
558: /*
559: --------------------------------------------------------------------------------
560: L'instruction ne correspond pas à l'un des mots clef du langage RPL/2.
561: --------------------------------------------------------------------------------
562: */
563:
564: if ((recherche_variable(s_etat_processus,
565: (*s_etat_processus).instruction_courante) ==
566: d_vrai) && ((*s_etat_processus)
567: .autorisation_evaluation_nom == 'Y'))
568: {
569: if ((*(*s_etat_processus).pointeur_variable_courante)
570: .objet == NULL)
571: {
572:
573: /*
574: --------------------------------------------------------------------------------
575: L'instruction est une variable partagée
576: --------------------------------------------------------------------------------
577: */
578:
579: if ((*s_etat_processus).debug == d_vrai)
580: if (((*s_etat_processus).type_debug &
581: d_debug_variables) != 0)
582: {
583: if ((*s_etat_processus).langue == 'F')
584: {
585: printf("[%d] Évaluation de la variable "
586: "partagée %s de type %d\n",
587: (int) getpid(), (*s_etat_processus)
588: .instruction_courante,
589: (*(*(*s_etat_processus)
590: .pointeur_variable_courante).objet)
591: .type);
592: }
593: else
594: {
595: printf("[%d] Pushing %s as %d type shared "
596: "variable \n", (int) getpid(),
597: (*s_etat_processus)
598: .instruction_courante,
599: (*(*(*s_etat_processus)
600: .pointeur_variable_courante).objet)
601: .type);
602: }
603:
604: fflush(stdout);
605: }
606:
607: if (pthread_mutex_lock(&((*(*s_etat_processus)
608: .s_liste_variables_partagees).mutex)) != 0)
609: {
610: (*s_etat_processus).erreur_systeme =
611: d_es_processus;
612: return(d_erreur);
613: }
614:
615: if (recherche_variable_partagee(s_etat_processus,
616: (*(*s_etat_processus)
617: .pointeur_variable_courante).nom,
618: (*(*s_etat_processus)
619: .pointeur_variable_courante).variable_partagee,
620: 'P') == d_vrai)
621: {
622: // La variable existe.
623:
624: if ((s_objet = copie_objet(s_etat_processus,
625: (*(*s_etat_processus)
626: .s_liste_variables_partagees)
627: .table[(*(*s_etat_processus)
628: .s_liste_variables_partagees)
629: .position_variable].objet, 'P'))
630: == NULL)
631: {
632: (*s_etat_processus).erreur_systeme =
633: d_es_allocation_memoire;
634: return(d_erreur);
635: }
636:
637: if (pthread_mutex_unlock(&((*(*s_etat_processus)
638: .s_liste_variables_partagees).mutex))
639: != 0)
640: {
641: (*s_etat_processus).erreur_systeme =
642: d_es_processus;
643: return(d_erreur);
644: }
645:
646: if (evaluation(s_etat_processus, s_objet, 'E')
647: == d_erreur)
648: {
649: liberation(s_etat_processus, s_objet);
650: return(d_erreur);
651: }
652:
653: liberation(s_etat_processus, s_objet);
654: }
655: else
656: {
657: // La variable n'existe plus.
658:
659: if (pthread_mutex_unlock(&((*(*s_etat_processus)
660: .s_liste_variables_partagees).mutex))
661: != 0)
662: {
663: (*s_etat_processus).erreur_systeme =
664: d_es_processus;
665: return(d_erreur);
666: }
667: }
668: }
669:
670: /*
671: --------------------------------------------------------------------------------
672: L'instruction est une variable automatique (évaluation lors de l'empilement).
673: --------------------------------------------------------------------------------
674: */
675:
676: else if ((*(*(*s_etat_processus).pointeur_variable_courante)
677: .objet).type == ADR)
678: {
679:
680: /*
681: --------------------------------------------------------------------------------
682: L'instruction est une variable de type 'adresse' pointant sur une
683: définition. Un branchement est effectué à cette adresse.
684: --------------------------------------------------------------------------------
685: */
686:
687: if ((*s_etat_processus).debug == d_vrai)
688: if (((*s_etat_processus).type_debug &
689: d_debug_appels_fonctions) != 0)
690: {
691: if ((*s_etat_processus).langue == 'F')
692: {
693: printf("[%d] Branchement à la"
694: " définition %s\n", (int) getpid(),
695: (*s_etat_processus)
696: .instruction_courante);
697: }
698: else
699: {
700: printf("[%d] Execution : "
701: "Branching at %s definition\n",
702: (int) getpid(), (*s_etat_processus)
703: .instruction_courante);
704: }
705:
706: fflush(stdout);
707: }
708:
709: (*s_etat_processus).autorisation_empilement_programme =
710: 'N';
711:
712: empilement_pile_systeme(s_etat_processus);
713:
714: if ((*s_etat_processus).erreur_systeme != d_es)
715: {
716: erreur = d_erreur;
717: }
718: else
719: {
720: if ((*s_etat_processus).profilage == d_vrai)
721: {
722: profilage(s_etat_processus,
723: (*s_etat_processus)
724: .instruction_courante);
725:
726: if ((*s_etat_processus).erreur_systeme != d_es)
727: {
728: return(d_erreur);
729: }
730: }
731:
732: (*(*s_etat_processus).l_base_pile_systeme)
733: .adresse_retour = (*s_etat_processus)
734: .position_courante;
735:
736: (*(*s_etat_processus).l_base_pile_systeme)
737: .retour_definition = 'Y';
738:
739: (*(*s_etat_processus).l_base_pile_systeme)
740: .niveau_courant = (*s_etat_processus)
741: .niveau_courant;
742:
743: (*s_etat_processus).position_courante =
744: (*((unsigned long *)
745: ((*(*(*s_etat_processus)
746: .pointeur_variable_courante)
747: .objet).objet)));
748:
749: drapeau_appel_definition = d_vrai;
750: }
751: }
752: else
753: {
754: if ((*s_etat_processus).debug == d_vrai)
755: if (((*s_etat_processus).type_debug &
756: d_debug_variables) != 0)
757: {
758: if ((*s_etat_processus).langue == 'F')
759: {
760: printf("[%d] Évaluation de la variable "
761: "%s de type %d\n",
762: (int) getpid(),
763: (*s_etat_processus)
764: .instruction_courante,
765: (*(*(*s_etat_processus)
766: .pointeur_variable_courante).objet)
767: .type);
768: }
769: else
770: {
771: printf("[%d] Pushing %s as %d type variable "
772: "\n", (int) getpid(),
773: (*s_etat_processus)
774: .instruction_courante,
775: (*(*(*s_etat_processus)
776: .pointeur_variable_courante).objet)
777: .type);
778: }
779:
780: fflush(stdout);
781: }
782:
783: if ((s_objet = copie_objet(s_etat_processus,
784: (*(*s_etat_processus)
785: .pointeur_variable_courante).objet, 'P'))
786: == NULL)
787: {
788: (*s_etat_processus).erreur_systeme =
789: d_es_allocation_memoire;
790: return(d_erreur);
791: }
792:
793: if (evaluation(s_etat_processus, s_objet, 'E')
794: == d_erreur)
795: {
796: liberation(s_etat_processus, s_objet);
797: return(d_erreur);
798: }
799:
800: liberation(s_etat_processus, s_objet);
801: }
802: }
803: else
804: {
805:
806: /*
807: --------------------------------------------------------------------------------
808: L'instruction est une donnée à empiler.
809: --------------------------------------------------------------------------------
810: */
811:
812: (*s_etat_processus).erreur_systeme = d_es;
813: recherche_type(s_etat_processus);
814:
815: if ((*s_etat_processus).autorisation_nom_implicite == 'N')
816: {
817: if ((*s_etat_processus).l_base_pile == NULL)
818: {
819: if ((*s_etat_processus).erreur_execution !=
820: d_ex_nom_implicite)
821: {
822: (*s_etat_processus).erreur_execution =
823: d_ex_manque_argument;
824: }
825: }
826: else if ((*(*(*s_etat_processus).l_base_pile).donnee)
827: .type == NOM)
828: {
829: if ((*((struct_nom *) (*(*(*s_etat_processus)
830: .l_base_pile).donnee).objet)).symbole
831: == d_faux)
832: {
833: (*s_etat_processus).erreur_execution =
834: d_ex_nom_implicite;
835:
836: // Si le niveau de récursivité est non nul, on
837: // arrive ici depuis la fonction
838: // recherche_type(). On retourne à cette
839: // dernière en indiquant une erreur.
840:
841: if ((*s_etat_processus).niveau_recursivite != 0)
842: {
843: free((*s_etat_processus)
844: .instruction_courante);
845: return(d_erreur);
846: }
847: }
848: }
849: }
850:
851: // Le séquenceur est appelé depuis la routine d'évaluation
852:
853: if ((*s_etat_processus).evaluation_forcee == 'Y')
854: {
855: if (depilement(s_etat_processus,
856: &((*s_etat_processus).l_base_pile),
857: &s_objet_evaluation) == d_erreur)
858: {
859: free((*s_etat_processus).instruction_courante);
860: (*s_etat_processus).erreur_execution =
861: d_ex_manque_argument;
862: return(d_erreur);
863: }
864:
865: if (evaluation(s_etat_processus, s_objet_evaluation,
866: 'N') == d_erreur)
867: {
868: free((*s_etat_processus).instruction_courante);
869: liberation(s_etat_processus, s_objet_evaluation);
870: return(d_erreur);
871: }
872:
873: liberation(s_etat_processus, s_objet_evaluation);
874: }
875:
876: // Le séquenceur est appelé depuis la routine de
877: // recherche de type
878:
879: else if ((*s_etat_processus).recherche_type == 'Y')
880: {
881: if ((*s_etat_processus).erreur_execution != d_ex)
882: {
883: free((*s_etat_processus).instruction_courante);
884: return(d_erreur);
885: }
886: }
887: }
888: }
889: else if (((*s_etat_processus).test_instruction == 'Y') &&
890: ((*s_etat_processus).instruction_valide == 'Y'))
891: {
892:
893: /*
894: --------------------------------------------------------------------------------
895: Permet de traiter les fonctions dans les objets de type liste
896: --------------------------------------------------------------------------------
897: */
898:
899: if ((instruction_majuscule = conversion_majuscule(
900: (*s_etat_processus).instruction_courante)) == NULL)
901: {
902: (*s_etat_processus).erreur_systeme =
903: d_es_allocation_memoire;
904: return(d_erreur);
905: }
906:
907: if ((strcmp((*s_etat_processus).instruction_courante, "<<")
908: != 0) && (strcmp((*s_etat_processus)
909: .instruction_courante, ">>") != 0))
910: {
911: if ((s_objet = allocation(s_etat_processus, FCT)) == NULL)
912: {
913: (*s_etat_processus).erreur_systeme =
914: d_es_allocation_memoire;
915: return(d_erreur);
916: }
917:
918: (*((struct_fonction *) (*s_objet).objet))
919: .nombre_arguments = 0;
920:
921: if ((*s_etat_processus).instruction_intrinseque == 'Y')
922: {
923: if (((*((struct_fonction *) (*s_objet).objet))
924: .nom_fonction = conversion_majuscule(
925: (*s_etat_processus).instruction_courante))
926: == NULL)
927: {
928: (*s_etat_processus).erreur_systeme =
929: d_es_allocation_memoire;
930: return(d_erreur);
931: }
932: }
933: else
934: {
935: if (((*((struct_fonction *) (*s_objet).objet))
936: .nom_fonction = (unsigned char *) malloc(
937: (strlen((*s_etat_processus)
938: .instruction_courante)
939: + 1) * sizeof(unsigned char))) == NULL)
940: {
941: (*s_etat_processus).erreur_systeme =
942: d_es_allocation_memoire;
943: return(d_erreur);
944: }
945:
946: strcpy((*((struct_fonction *) (*s_objet).objet))
947: .nom_fonction, (*s_etat_processus)
948: .instruction_courante);
949: }
950:
951: (*((struct_fonction *) (*s_objet).objet)).fonction =
952: analyse_instruction(s_etat_processus,
953: (*s_etat_processus).instruction_courante);
954:
955: if (empilement(s_etat_processus,
956: &((*s_etat_processus).l_base_pile), s_objet) ==
957: d_erreur)
958: {
959: (*s_etat_processus).erreur_systeme =
960: d_es_allocation_memoire;
961: return(d_erreur);
962: }
963: }
964: else
965: {
966: (*s_etat_processus).test_instruction = 'N';
967: analyse(s_etat_processus, NULL);
968: (*s_etat_processus).test_instruction = 'Y';
969: }
970:
971: free(instruction_majuscule);
972: }
973:
974: erreur |= (((*s_etat_processus).erreur_execution != d_ex)
975: ? d_erreur : d_absence_erreur);
976: }
977: else
978: {
979: printf("\n");
980:
981: if ((*s_etat_processus).langue == 'F')
982: {
983: printf("+++Erreur : Argument %s invalide\n",
984: (*s_etat_processus).instruction_courante);
985: }
986: else
987: {
988: printf("+++Error : Invalid %s argument\n",
989: (*s_etat_processus).instruction_courante);
990: }
991:
992: fflush(stdout);
993:
994: free((*s_etat_processus).instruction_courante);
995: return(d_erreur);
996: }
997:
998: /*
999: --------------------------------------------------------------------------------
1000: Traitement des arrêts simples
1001: --------------------------------------------------------------------------------
1002: */
1003:
1004: if ((*s_etat_processus).var_volatile_requete_arret2 != 0)
1005: {
1006: if ((*s_etat_processus).debug_programme == d_vrai)
1007: {
1008: (*s_etat_processus).var_volatile_requete_arret2 = 0;
1009: }
1010: else
1011: {
1012: if ((*s_etat_processus).var_volatile_requete_arret2 == -1)
1013: {
1014: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1015: {
1016: printf("[%d] Arrêt\n", (int) getpid());
1017: }
1018: else
1019: {
1020: printf("[%d] Break\n", (int) getpid());
1021: }
1022:
1023: (*s_etat_processus).var_volatile_requete_arret2 = 1;
1024:
1025: fflush(stdout);
1026: }
1027:
1028: if ((*s_etat_processus).niveau_recursivite == 0)
1029: {
1030: (*s_etat_processus).debug_programme = d_vrai;
1031: (*s_etat_processus).var_volatile_requete_arret2 = 0;
1032: }
1033: }
1034: }
1035:
1036: /*
1037: * On ne sort pas du debugger en cas d'une erreur sur un programme
1038: * en cours de débogage.
1039: */
1040:
1041: if ((((*s_etat_processus).erreur_execution != d_ex) ||
1042: ((*s_etat_processus).exception != d_ep)) &&
1043: ((*s_etat_processus).debug_programme == d_vrai))
1044: {
1045: if (test_cfsf(s_etat_processus, 31) == d_vrai)
1046: {
1047: l_element_courant = (*s_etat_processus).l_base_pile_last;
1048:
1049: while(l_element_courant != NULL)
1050: {
1051: if ((s_objet = copie_objet(s_etat_processus,
1052: (*l_element_courant).donnee, 'P')) == NULL)
1053: {
1054: (*s_etat_processus).erreur_systeme =
1055: d_es_allocation_memoire;
1056: return(d_erreur);
1057: }
1058:
1059: if (empilement(s_etat_processus, &((*s_etat_processus)
1060: .l_base_pile), s_objet) == d_erreur)
1061: {
1062: return(d_erreur);
1063: }
1064:
1065: l_element_courant = (*l_element_courant).suivant;
1066: }
1067: }
1068:
1069: if (test_cfsf(s_etat_processus, 51) == d_faux)
1070: {
1071: printf("%s", ds_beep);
1072: }
1073:
1074: if ((message = messages(s_etat_processus)) == NULL)
1075: {
1076: free((*s_etat_processus).instruction_courante);
1077: return(d_erreur);
1078: }
1079:
1080: printf("%s [%d]\n", message, (int) getpid());
1081:
1082: free(message);
1083:
1084: (*s_etat_processus).erreur_execution = d_ex;
1085: (*s_etat_processus).exception = d_ep;
1086: erreur = d_absence_erreur;
1087:
1088: (*s_etat_processus).position_courante -=
1089: strlen((*s_etat_processus).instruction_courante);
1090: }
1091:
1092: /*
1093: --------------------------------------------------------------------------------
1094: Test de fin d'exécution du programme RPL/2
1095: --------------------------------------------------------------------------------
1096: */
1097:
1098: if (((*s_etat_processus).niveau_courant == 0) &&
1099: (drapeau_appel_definition != d_vrai))
1100: {
1101: drapeau_fin = d_vrai;
1102: }
1103: else if ((*s_etat_processus).requete_arret == 'Y')
1104: {
1105: drapeau_fin = d_vrai;
1106: }
1107: else if (((*s_etat_processus).var_volatile_requete_arret != 0)
1108: && ((*s_etat_processus).debug_programme == d_faux))
1109: {
1110: drapeau_fin = d_vrai;
1111:
1112: if ((*s_etat_processus).erreur_systeme == d_es)
1113: {
1114: erreur = d_absence_erreur;
1115: }
1116: }
1117: else if ((*s_etat_processus).arret_si_exception == d_vrai)
1118: {
1119: drapeau_fin = d_faux;
1120:
1121: if ((*s_etat_processus).exception != d_ep)
1122: {
1123: erreur = d_erreur;
1124: }
1125: else if ((*s_etat_processus).erreur_systeme != d_es)
1126: {
1127: erreur = d_erreur;
1128: }
1129: }
1130: else if ((*s_etat_processus).arret_si_exception == d_faux)
1131: {
1132: if ((message = messages(s_etat_processus)) == NULL)
1133: {
1134: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1135: return(d_erreur);
1136: }
1137:
1138: free(message);
1139:
1140: drapeau_fin = d_faux;
1141:
1142: /*
1143: --------------------------------------------------------------------------------
1144: Traitement des exceptions
1145: --------------------------------------------------------------------------------
1146: */
1147:
1148: if ((*s_etat_processus).erreur_systeme != d_es)
1149: {
1150: erreur = d_erreur;
1151: }
1152: else if (((*s_etat_processus).exception != d_ep) ||
1153: ((*s_etat_processus).erreur_execution != d_ex))
1154: {
1155: tampon = (*s_etat_processus).instruction_courante;
1156:
1157: while((*(*s_etat_processus).l_base_pile_systeme).clause != 'R')
1158: {
1159: erreur = recherche_instruction_suivante(s_etat_processus);
1160:
1161: if (erreur == d_erreur)
1162: {
1163: free((*s_etat_processus).instruction_courante);
1164: return(d_erreur);
1165: }
1166:
1167: if (recherche_variable(s_etat_processus,
1168: (*s_etat_processus).instruction_courante) == d_vrai)
1169: {
1170: if ((*(*s_etat_processus).pointeur_variable_courante)
1171: .objet == NULL)
1172: {
1173: // Variable partagée
1174: }
1175: else if ((*(*(*s_etat_processus)
1176: .pointeur_variable_courante).objet).type == ADR)
1177: {
1178: empilement_pile_systeme(s_etat_processus);
1179:
1180: if ((*s_etat_processus).erreur_systeme != d_es)
1181: {
1182: free((*s_etat_processus).instruction_courante);
1183: return(d_erreur);
1184: }
1185:
1186: (*(*s_etat_processus).l_base_pile_systeme)
1187: .adresse_retour = (*s_etat_processus)
1188: .position_courante;
1189:
1190: (*(*s_etat_processus).l_base_pile_systeme)
1191: .retour_definition = 'Y';
1192:
1193: (*(*s_etat_processus).l_base_pile_systeme)
1194: .niveau_courant = (*s_etat_processus)
1195: .niveau_courant;
1196:
1197: (*s_etat_processus).position_courante =
1198: (*((unsigned long *)
1199: ((*(*(*s_etat_processus)
1200: .pointeur_variable_courante)
1201: .objet).objet)));
1202:
1203: (*s_etat_processus)
1204: .autorisation_empilement_programme = 'N';
1205: }
1206: }
1207: else
1208: {
1209: (*s_etat_processus).erreur_systeme = d_es;
1210: instruction_majuscule = conversion_majuscule(
1211: (*s_etat_processus).instruction_courante);
1212:
1213: if (instruction_majuscule == NULL)
1214: {
1215: free((*s_etat_processus).instruction_courante);
1216: return(d_erreur);
1217: }
1218:
1219: /*
1220: * Traitement de la pile système par les
1221: * différentes instructions.
1222: */
1223:
1224: if ((strcmp(instruction_majuscule, "IF") == 0) ||
1225: (strcmp(instruction_majuscule, "IFERR") == 0) ||
1226: (strcmp(instruction_majuscule, "DO") == 0) ||
1227: (strcmp(instruction_majuscule, "WHILE") == 0) ||
1228: (strcmp(instruction_majuscule, "FOR") == 0) ||
1229: (strcmp(instruction_majuscule, "FORALL") == 0)
1230: ||
1231: (strcmp(instruction_majuscule, "START") == 0) ||
1232: (strcmp(instruction_majuscule, "SELECT") == 0)
1233: ||
1234: (strcmp(instruction_majuscule, "CRITICAL") == 0)
1235: || (strcmp(instruction_majuscule, "CASE") == 0)
1236: || (strcmp(instruction_majuscule, "<<") == 0))
1237: {
1238: if (strcmp(instruction_majuscule, "<<") == 0)
1239: {
1240: analyse(s_etat_processus, NULL);
1241: }
1242: else if ((strcmp(instruction_majuscule, "FOR") == 0)
1243: || (strcmp(instruction_majuscule, "FORALL")
1244: == 0) || (strcmp(instruction_majuscule,
1245: "START") == 0))
1246: {
1247: empilement_pile_systeme(s_etat_processus);
1248:
1249: if ((*s_etat_processus).erreur_systeme != d_es)
1250: {
1251: return(d_erreur);
1252: }
1253:
1254: (*(*s_etat_processus).l_base_pile_systeme)
1255: .type_cloture = 'L';
1256: }
1257: else
1258: {
1259: empilement_pile_systeme(s_etat_processus);
1260:
1261: if ((*s_etat_processus).erreur_systeme != d_es)
1262: {
1263: return(d_erreur);
1264: }
1265: }
1266: }
1267: else if ((strcmp(instruction_majuscule, "END") == 0) ||
1268: (strcmp(instruction_majuscule, "NEXT") == 0) ||
1269: (strcmp(instruction_majuscule, "STEP") == 0) ||
1270: (strcmp(instruction_majuscule, ">>") == 0))
1271: {
1272: if (strcmp(instruction_majuscule, ">>") == 0)
1273: {
1274: analyse(s_etat_processus, NULL);
1275:
1276: if ((*(*s_etat_processus).l_base_pile_systeme)
1277: .origine_routine_evaluation == 'Y')
1278: {
1279: free(instruction_majuscule);
1280: free((*s_etat_processus)
1281: .instruction_courante);
1282:
1283: (*s_etat_processus).instruction_courante =
1284: tampon;
1285:
1286: return(d_absence_erreur);
1287: }
1288: }
1289: else if (((strcmp(instruction_majuscule, "NEXT")
1290: == 0) || (strcmp(instruction_majuscule,
1291: "STEP") == 0)) && ((*(*s_etat_processus)
1292: .l_base_pile_systeme).type_cloture != 'L'))
1293: {
1294: /*
1295: * Libération des compteurs de boucle.
1296: */
1297:
1298: presence_compteur = (((*(*s_etat_processus)
1299: .l_base_pile_systeme).type_cloture
1300: == 'F') || ((*(*s_etat_processus)
1301: .l_base_pile_systeme).type_cloture
1302: == 'A')) ? d_vrai : d_faux;
1303:
1304: if (((*(*s_etat_processus).l_base_pile_systeme)
1305: .type_cloture != 'S') &&
1306: (presence_compteur == d_faux))
1307: {
1308: return(d_erreur);
1309: }
1310:
1311: if (presence_compteur == d_vrai)
1312: {
1313: if (recherche_variable(s_etat_processus,
1314: (*(*s_etat_processus)
1315: .l_base_pile_systeme).nom_variable)
1316: == d_faux)
1317: {
1318: return(d_erreur);
1319: }
1320:
1321: if ((*(*s_etat_processus)
1322: .pointeur_variable_courante).objet
1323: == NULL)
1324: {
1325: return(d_erreur);
1326: }
1327:
1328: (*s_etat_processus).niveau_courant--;
1329:
1330: if (retrait_variables_par_niveau(
1331: s_etat_processus) == d_erreur)
1332: {
1333: return(d_erreur);
1334: }
1335: }
1336:
1337: depilement_pile_systeme(s_etat_processus);
1338:
1339: if ((*s_etat_processus).erreur_systeme != d_es)
1340: {
1341: return(d_erreur);
1342: }
1343: }
1344: else
1345: {
1346: // Traitement spécifique pour la fin
1347: // d'une section critique
1348:
1349: if ((*s_etat_processus).l_base_pile_systeme
1350: == NULL)
1351: {
1352: (*s_etat_processus).erreur_systeme =
1353: d_es_processus;
1354: return(d_erreur);
1355: }
1356:
1357: if ((*(*s_etat_processus).l_base_pile_systeme)
1358: .type_cloture == 'Q')
1359: {
1360: if (pthread_mutex_unlock(
1361: &mutex_sections_critiques) != 0)
1362: {
1363: (*s_etat_processus).erreur_systeme =
1364: d_es_processus;
1365: return(d_erreur);
1366: }
1367:
1368: (*s_etat_processus).sections_critiques--;
1369: }
1370:
1371: depilement_pile_systeme(s_etat_processus);
1372:
1373: if ((*s_etat_processus).erreur_systeme != d_es)
1374: {
1375: return(d_erreur);
1376: }
1377: }
1378: }
1379:
1380: free(instruction_majuscule);
1381: }
1382:
1383: free((*s_etat_processus).instruction_courante);
1384: }
1385:
1386: drapeau_then = d_faux;
1387: niveau = 0;
1388:
1389: do
1390: {
1391: erreur = recherche_instruction_suivante(s_etat_processus);
1392:
1393: if (erreur == d_erreur)
1394: {
1395: return(d_erreur);
1396: }
1397:
1398: instruction_majuscule = conversion_majuscule(
1399: (*s_etat_processus).instruction_courante);
1400:
1401: if (instruction_majuscule == NULL)
1402: {
1403: return(d_erreur);
1404: }
1405:
1406: if ((strcmp(instruction_majuscule, "IF") == 0) ||
1407: (strcmp(instruction_majuscule, "IFERR") == 0) ||
1408: (strcmp(instruction_majuscule, "DO") == 0) ||
1409: (strcmp(instruction_majuscule, "WHILE") == 0) ||
1410: (strcmp(instruction_majuscule, "FOR") == 0) ||
1411: (strcmp(instruction_majuscule, "FORALL") == 0) ||
1412: (strcmp(instruction_majuscule, "START") == 0) ||
1413: (strcmp(instruction_majuscule, "SELECT") == 0)
1414: || (strcmp(instruction_majuscule, "CRITICAL") == 0)
1415: || (strcmp(instruction_majuscule, "CASE") == 0)
1416: || (strcmp(instruction_majuscule, "<<") == 0))
1417: {
1418: niveau++;
1419: }
1420: else if ((strcmp(instruction_majuscule, "END") == 0) ||
1421: (strcmp(instruction_majuscule, "NEXT") == 0) ||
1422: (strcmp(instruction_majuscule, "STEP") == 0) ||
1423: (strcmp(instruction_majuscule, ">>") == 0))
1424: {
1425: niveau--;
1426: }
1427:
1428: drapeau_then = ((strcmp(instruction_majuscule, "THEN") == 0)
1429: && (niveau == 0)) ? d_vrai : d_faux;
1430:
1431: free(instruction_majuscule);
1432: free((*s_etat_processus).instruction_courante);
1433: } while(drapeau_then == d_faux);
1434:
1435: (*s_etat_processus).position_courante -= 5;
1436: (*s_etat_processus).instruction_courante = tampon;
1437: (*(*s_etat_processus).l_base_pile_systeme).clause = 'X';
1438:
1439: erreur = d_absence_erreur;
1440: (*s_etat_processus).exception = d_ep;
1441: (*s_etat_processus).erreur_execution = d_ex;
1442: }
1443: }
1444: else
1445: {
1446: drapeau_fin = d_faux;
1447: }
1448:
1449: if (erreur == d_absence_erreur)
1450: {
1451: free((*s_etat_processus).instruction_courante);
1452: }
1453: } while((erreur == d_absence_erreur) &&
1454: ((*s_etat_processus).position_courante <
1455: (*s_etat_processus).longueur_definitions_chainees) &&
1456: (drapeau_fin == d_faux) &&
1457: ((*s_etat_processus).retour_routine_evaluation == 'N'));
1458:
1459: /*
1460: --------------------------------------------------------------------------------
1461: Messages d'erreur à afficher le cas échéant
1462: --------------------------------------------------------------------------------
1463: */
1464:
1465: if ((erreur != d_absence_erreur) && ((*s_etat_processus)
1466: .invalidation_message_erreur == d_faux))
1467: {
1468: if (test_cfsf(s_etat_processus, 31) == d_vrai)
1469: {
1470: l_element_courant = (*s_etat_processus).l_base_pile_last;
1471:
1472: while(l_element_courant != NULL)
1473: {
1474: if ((s_objet = copie_objet(s_etat_processus,
1475: (*l_element_courant).donnee, 'P')) == NULL)
1476: {
1477: (*s_etat_processus).erreur_systeme =
1478: d_es_allocation_memoire;
1479: return(d_erreur);
1480: }
1481:
1482: if (empilement(s_etat_processus, &((*s_etat_processus)
1483: .l_base_pile), s_objet) == d_erreur)
1484: {
1485: return(d_erreur);
1486: }
1487:
1488: l_element_courant = (*l_element_courant).suivant;
1489: }
1490: }
1491:
1492: if (test_cfsf(s_etat_processus, 51) == d_faux)
1493: {
1494: printf("%s", ds_beep);
1495: }
1496:
1497: if ((message = messages(s_etat_processus)) == NULL)
1498: {
1499: return(d_erreur);
1500: }
1501:
1502: printf("%s [%d]\n", message, (int) getpid());
1503:
1504: free(message);
1505: free((*s_etat_processus).instruction_courante);
1506:
1507: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1508: {
1509: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1510: rpl_sigalrm);
1511: }
1512: else
1513: {
1514: (*s_etat_processus).var_volatile_alarme = -1;
1515: }
1516:
1517: return(d_erreur);
1518: }
1519:
1520: return(d_absence_erreur);
1521: }
1522:
1523: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>