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 (recherche_variable_partagee(s_etat_processus,
608: (*(*s_etat_processus)
609: .pointeur_variable_courante).nom,
610: (*(*s_etat_processus)
611: .pointeur_variable_courante).variable_partagee,
612: 'P') != NULL)
613: {
614: // La variable existe.
615:
616: if ((s_objet = copie_objet(s_etat_processus,
617: (*(*s_etat_processus)
618: .pointeur_variable_partagee_courante)
619: .objet, 'P')) == NULL)
620: {
621: (*s_etat_processus).erreur_systeme =
622: d_es_allocation_memoire;
623: return(d_erreur);
624: }
625:
626: if (pthread_mutex_unlock(&((*(*s_etat_processus)
627: .pointeur_variable_partagee_courante)
628: .mutex)) != 0)
629: {
630: (*s_etat_processus).erreur_systeme =
631: d_es_processus;
632: return(d_erreur);
633: }
634:
635: if (evaluation(s_etat_processus, s_objet, 'E')
636: == d_erreur)
637: {
638: liberation(s_etat_processus, s_objet);
639: return(d_erreur);
640: }
641:
642: liberation(s_etat_processus, s_objet);
643: }
644: else
645: {
646: // La variable n'existe plus.
647: }
648: }
649:
650: /*
651: --------------------------------------------------------------------------------
652: L'instruction est une variable automatique (évaluation lors de l'empilement).
653: --------------------------------------------------------------------------------
654: */
655:
656: else if ((*(*(*s_etat_processus).pointeur_variable_courante)
657: .objet).type == ADR)
658: {
659:
660: /*
661: --------------------------------------------------------------------------------
662: L'instruction est une variable de type 'adresse' pointant sur une
663: définition. Un branchement est effectué à cette adresse.
664: --------------------------------------------------------------------------------
665: */
666:
667: if ((*s_etat_processus).debug == d_vrai)
668: if (((*s_etat_processus).type_debug &
669: d_debug_appels_fonctions) != 0)
670: {
671: if ((*s_etat_processus).langue == 'F')
672: {
673: printf("[%d] Branchement à la"
674: " définition %s\n", (int) getpid(),
675: (*s_etat_processus)
676: .instruction_courante);
677: }
678: else
679: {
680: printf("[%d] Execution : "
681: "Branching at %s definition\n",
682: (int) getpid(), (*s_etat_processus)
683: .instruction_courante);
684: }
685:
686: fflush(stdout);
687: }
688:
689: (*s_etat_processus).autorisation_empilement_programme =
690: 'N';
691:
692: empilement_pile_systeme(s_etat_processus);
693:
694: if ((*s_etat_processus).erreur_systeme != d_es)
695: {
696: erreur = d_erreur;
697: }
698: else
699: {
700: if ((*s_etat_processus).profilage == d_vrai)
701: {
702: profilage(s_etat_processus,
703: (*s_etat_processus)
704: .instruction_courante);
705:
706: if ((*s_etat_processus).erreur_systeme != d_es)
707: {
708: return(d_erreur);
709: }
710: }
711:
712: (*(*s_etat_processus).l_base_pile_systeme)
713: .adresse_retour = (*s_etat_processus)
714: .position_courante;
715:
716: (*(*s_etat_processus).l_base_pile_systeme)
717: .retour_definition = 'Y';
718:
719: (*(*s_etat_processus).l_base_pile_systeme)
720: .niveau_courant = (*s_etat_processus)
721: .niveau_courant;
722:
723: (*s_etat_processus).position_courante =
724: (*((unsigned long *)
725: ((*(*(*s_etat_processus)
726: .pointeur_variable_courante)
727: .objet).objet)));
728:
729: drapeau_appel_definition = d_vrai;
730: }
731: }
732: else
733: {
734: if ((*s_etat_processus).debug == d_vrai)
735: if (((*s_etat_processus).type_debug &
736: d_debug_variables) != 0)
737: {
738: if ((*s_etat_processus).langue == 'F')
739: {
740: printf("[%d] Évaluation de la variable "
741: "%s de type %d\n",
742: (int) getpid(),
743: (*s_etat_processus)
744: .instruction_courante,
745: (*(*(*s_etat_processus)
746: .pointeur_variable_courante).objet)
747: .type);
748: }
749: else
750: {
751: printf("[%d] Pushing %s as %d type variable "
752: "\n", (int) getpid(),
753: (*s_etat_processus)
754: .instruction_courante,
755: (*(*(*s_etat_processus)
756: .pointeur_variable_courante).objet)
757: .type);
758: }
759:
760: fflush(stdout);
761: }
762:
763: if ((s_objet = copie_objet(s_etat_processus,
764: (*(*s_etat_processus)
765: .pointeur_variable_courante).objet, 'P'))
766: == NULL)
767: {
768: (*s_etat_processus).erreur_systeme =
769: d_es_allocation_memoire;
770: return(d_erreur);
771: }
772:
773: if (evaluation(s_etat_processus, s_objet, 'E')
774: == d_erreur)
775: {
776: liberation(s_etat_processus, s_objet);
777: return(d_erreur);
778: }
779:
780: liberation(s_etat_processus, s_objet);
781: }
782: }
783: else
784: {
785:
786: /*
787: --------------------------------------------------------------------------------
788: L'instruction est une donnée à empiler.
789: --------------------------------------------------------------------------------
790: */
791:
792: (*s_etat_processus).erreur_systeme = d_es;
793: recherche_type(s_etat_processus);
794:
795: if ((*s_etat_processus).autorisation_nom_implicite == 'N')
796: {
797: if ((*s_etat_processus).l_base_pile == NULL)
798: {
799: if ((*s_etat_processus).erreur_execution !=
800: d_ex_nom_implicite)
801: {
802: (*s_etat_processus).erreur_execution =
803: d_ex_manque_argument;
804: }
805: }
806: else if ((*(*(*s_etat_processus).l_base_pile).donnee)
807: .type == NOM)
808: {
809: if ((*((struct_nom *) (*(*(*s_etat_processus)
810: .l_base_pile).donnee).objet)).symbole
811: == d_faux)
812: {
813: (*s_etat_processus).erreur_execution =
814: d_ex_nom_implicite;
815:
816: // Si le niveau de récursivité est non nul, on
817: // arrive ici depuis la fonction
818: // recherche_type(). On retourne à cette
819: // dernière en indiquant une erreur.
820:
821: if ((*s_etat_processus).niveau_recursivite != 0)
822: {
823: free((*s_etat_processus)
824: .instruction_courante);
825: return(d_erreur);
826: }
827: }
828: }
829: }
830:
831: // Le séquenceur est appelé depuis la routine d'évaluation
832:
833: if ((*s_etat_processus).evaluation_forcee == 'Y')
834: {
835: if (depilement(s_etat_processus,
836: &((*s_etat_processus).l_base_pile),
837: &s_objet_evaluation) == d_erreur)
838: {
839: free((*s_etat_processus).instruction_courante);
840: (*s_etat_processus).erreur_execution =
841: d_ex_manque_argument;
842: return(d_erreur);
843: }
844:
845: if (evaluation(s_etat_processus, s_objet_evaluation,
846: 'N') == d_erreur)
847: {
848: free((*s_etat_processus).instruction_courante);
849: liberation(s_etat_processus, s_objet_evaluation);
850: return(d_erreur);
851: }
852:
853: liberation(s_etat_processus, s_objet_evaluation);
854: }
855:
856: // Le séquenceur est appelé depuis la routine de
857: // recherche de type
858:
859: else if ((*s_etat_processus).recherche_type == 'Y')
860: {
861: if ((*s_etat_processus).erreur_execution != d_ex)
862: {
863: free((*s_etat_processus).instruction_courante);
864: return(d_erreur);
865: }
866: }
867: }
868: }
869: else if (((*s_etat_processus).test_instruction == 'Y') &&
870: ((*s_etat_processus).instruction_valide == 'Y'))
871: {
872:
873: /*
874: --------------------------------------------------------------------------------
875: Permet de traiter les fonctions dans les objets de type liste
876: --------------------------------------------------------------------------------
877: */
878:
879: if ((instruction_majuscule = conversion_majuscule(
880: (*s_etat_processus).instruction_courante)) == NULL)
881: {
882: (*s_etat_processus).erreur_systeme =
883: d_es_allocation_memoire;
884: return(d_erreur);
885: }
886:
887: if ((strcmp((*s_etat_processus).instruction_courante, "<<")
888: != 0) && (strcmp((*s_etat_processus)
889: .instruction_courante, ">>") != 0))
890: {
891: if ((s_objet = allocation(s_etat_processus, FCT)) == NULL)
892: {
893: (*s_etat_processus).erreur_systeme =
894: d_es_allocation_memoire;
895: return(d_erreur);
896: }
897:
898: (*((struct_fonction *) (*s_objet).objet))
899: .nombre_arguments = 0;
900:
901: if ((*s_etat_processus).instruction_intrinseque == 'Y')
902: {
903: if (((*((struct_fonction *) (*s_objet).objet))
904: .nom_fonction = conversion_majuscule(
905: (*s_etat_processus).instruction_courante))
906: == NULL)
907: {
908: (*s_etat_processus).erreur_systeme =
909: d_es_allocation_memoire;
910: return(d_erreur);
911: }
912: }
913: else
914: {
915: if (((*((struct_fonction *) (*s_objet).objet))
916: .nom_fonction = (unsigned char *) malloc(
917: (strlen((*s_etat_processus)
918: .instruction_courante)
919: + 1) * sizeof(unsigned char))) == NULL)
920: {
921: (*s_etat_processus).erreur_systeme =
922: d_es_allocation_memoire;
923: return(d_erreur);
924: }
925:
926: strcpy((*((struct_fonction *) (*s_objet).objet))
927: .nom_fonction, (*s_etat_processus)
928: .instruction_courante);
929: }
930:
931: (*((struct_fonction *) (*s_objet).objet)).fonction =
932: analyse_instruction(s_etat_processus,
933: (*s_etat_processus).instruction_courante);
934:
935: if (empilement(s_etat_processus,
936: &((*s_etat_processus).l_base_pile), s_objet) ==
937: d_erreur)
938: {
939: (*s_etat_processus).erreur_systeme =
940: d_es_allocation_memoire;
941: return(d_erreur);
942: }
943: }
944: else
945: {
946: (*s_etat_processus).test_instruction = 'N';
947: analyse(s_etat_processus, NULL);
948: (*s_etat_processus).test_instruction = 'Y';
949: }
950:
951: free(instruction_majuscule);
952: }
953:
954: erreur |= (((*s_etat_processus).erreur_execution != d_ex)
955: ? d_erreur : d_absence_erreur);
956: }
957: else
958: {
959: printf("\n");
960:
961: if ((*s_etat_processus).langue == 'F')
962: {
963: printf("+++Erreur : Argument %s invalide\n",
964: (*s_etat_processus).instruction_courante);
965: }
966: else
967: {
968: printf("+++Error : Invalid %s argument\n",
969: (*s_etat_processus).instruction_courante);
970: }
971:
972: fflush(stdout);
973:
974: free((*s_etat_processus).instruction_courante);
975: return(d_erreur);
976: }
977:
978: /*
979: --------------------------------------------------------------------------------
980: Traitement des arrêts simples
981: --------------------------------------------------------------------------------
982: */
983:
984: if ((*s_etat_processus).var_volatile_requete_arret2 != 0)
985: {
986: if ((*s_etat_processus).debug_programme == d_vrai)
987: {
988: (*s_etat_processus).var_volatile_requete_arret2 = 0;
989: }
990: else
991: {
992: if ((*s_etat_processus).var_volatile_requete_arret2 == -1)
993: {
994: if (strncmp(getenv("LANG"), "fr", 2) == 0)
995: {
996: printf("[%d] Arrêt\n", (int) getpid());
997: }
998: else
999: {
1000: printf("[%d] Break\n", (int) getpid());
1001: }
1002:
1003: (*s_etat_processus).var_volatile_requete_arret2 = 1;
1004:
1005: fflush(stdout);
1006: }
1007:
1008: if ((*s_etat_processus).niveau_recursivite == 0)
1009: {
1010: (*s_etat_processus).debug_programme = d_vrai;
1011: (*s_etat_processus).var_volatile_requete_arret2 = 0;
1012: }
1013: }
1014: }
1015:
1016: /*
1017: * On ne sort pas du debugger en cas d'une erreur sur un programme
1018: * en cours de débogage.
1019: */
1020:
1021: if ((((*s_etat_processus).erreur_execution != d_ex) ||
1022: ((*s_etat_processus).exception != d_ep)) &&
1023: ((*s_etat_processus).debug_programme == d_vrai))
1024: {
1025: if (test_cfsf(s_etat_processus, 31) == d_vrai)
1026: {
1027: l_element_courant = (*s_etat_processus).l_base_pile_last;
1028:
1029: while(l_element_courant != NULL)
1030: {
1031: if ((s_objet = copie_objet(s_etat_processus,
1032: (*l_element_courant).donnee, 'P')) == NULL)
1033: {
1034: (*s_etat_processus).erreur_systeme =
1035: d_es_allocation_memoire;
1036: return(d_erreur);
1037: }
1038:
1039: if (empilement(s_etat_processus, &((*s_etat_processus)
1040: .l_base_pile), s_objet) == d_erreur)
1041: {
1042: return(d_erreur);
1043: }
1044:
1045: l_element_courant = (*l_element_courant).suivant;
1046: }
1047: }
1048:
1049: if (test_cfsf(s_etat_processus, 51) == d_faux)
1050: {
1051: printf("%s", ds_beep);
1052: }
1053:
1054: if ((message = messages(s_etat_processus)) == NULL)
1055: {
1056: free((*s_etat_processus).instruction_courante);
1057: return(d_erreur);
1058: }
1059:
1060: printf("%s [%d]\n", message, (int) getpid());
1061:
1062: free(message);
1063:
1064: (*s_etat_processus).erreur_execution = d_ex;
1065: (*s_etat_processus).exception = d_ep;
1066: erreur = d_absence_erreur;
1067:
1068: (*s_etat_processus).position_courante -=
1069: strlen((*s_etat_processus).instruction_courante);
1070: }
1071:
1072: /*
1073: --------------------------------------------------------------------------------
1074: Test de fin d'exécution du programme RPL/2
1075: --------------------------------------------------------------------------------
1076: */
1077:
1078: if (((*s_etat_processus).niveau_courant == 0) &&
1079: (drapeau_appel_definition != d_vrai))
1080: {
1081: drapeau_fin = d_vrai;
1082: }
1083: else if ((*s_etat_processus).requete_arret == 'Y')
1084: {
1085: drapeau_fin = d_vrai;
1086: }
1087: else if (((*s_etat_processus).var_volatile_requete_arret != 0)
1088: && ((*s_etat_processus).debug_programme == d_faux))
1089: {
1090: drapeau_fin = d_vrai;
1091:
1092: if ((*s_etat_processus).erreur_systeme == d_es)
1093: {
1094: erreur = d_absence_erreur;
1095: }
1096: }
1097: else if ((*s_etat_processus).arret_si_exception == d_vrai)
1098: {
1099: drapeau_fin = d_faux;
1100:
1101: if ((*s_etat_processus).exception != d_ep)
1102: {
1103: erreur = d_erreur;
1104: }
1105: else if ((*s_etat_processus).erreur_systeme != d_es)
1106: {
1107: erreur = d_erreur;
1108: }
1109: }
1110: else if ((*s_etat_processus).arret_si_exception == d_faux)
1111: {
1112: if ((message = messages(s_etat_processus)) == NULL)
1113: {
1114: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1115: return(d_erreur);
1116: }
1117:
1118: free(message);
1119:
1120: drapeau_fin = d_faux;
1121:
1122: /*
1123: --------------------------------------------------------------------------------
1124: Traitement des exceptions
1125: --------------------------------------------------------------------------------
1126: */
1127:
1128: if ((*s_etat_processus).erreur_systeme != d_es)
1129: {
1130: erreur = d_erreur;
1131: }
1132: else if (((*s_etat_processus).exception != d_ep) ||
1133: ((*s_etat_processus).erreur_execution != d_ex))
1134: {
1135: tampon = (*s_etat_processus).instruction_courante;
1136:
1137: while((*(*s_etat_processus).l_base_pile_systeme).clause != 'R')
1138: {
1139: erreur = recherche_instruction_suivante(s_etat_processus);
1140:
1141: if (erreur == d_erreur)
1142: {
1143: free((*s_etat_processus).instruction_courante);
1144: return(d_erreur);
1145: }
1146:
1147: if (recherche_variable(s_etat_processus,
1148: (*s_etat_processus).instruction_courante) == d_vrai)
1149: {
1150: if ((*(*s_etat_processus).pointeur_variable_courante)
1151: .objet == NULL)
1152: {
1153: // Variable partagée
1154: }
1155: else if ((*(*(*s_etat_processus)
1156: .pointeur_variable_courante).objet).type == ADR)
1157: {
1158: empilement_pile_systeme(s_etat_processus);
1159:
1160: if ((*s_etat_processus).erreur_systeme != d_es)
1161: {
1162: free((*s_etat_processus).instruction_courante);
1163: return(d_erreur);
1164: }
1165:
1166: (*(*s_etat_processus).l_base_pile_systeme)
1167: .adresse_retour = (*s_etat_processus)
1168: .position_courante;
1169:
1170: (*(*s_etat_processus).l_base_pile_systeme)
1171: .retour_definition = 'Y';
1172:
1173: (*(*s_etat_processus).l_base_pile_systeme)
1174: .niveau_courant = (*s_etat_processus)
1175: .niveau_courant;
1176:
1177: (*s_etat_processus).position_courante =
1178: (*((unsigned long *)
1179: ((*(*(*s_etat_processus)
1180: .pointeur_variable_courante)
1181: .objet).objet)));
1182:
1183: (*s_etat_processus)
1184: .autorisation_empilement_programme = 'N';
1185: }
1186: }
1187: else
1188: {
1189: (*s_etat_processus).erreur_systeme = d_es;
1190: instruction_majuscule = conversion_majuscule(
1191: (*s_etat_processus).instruction_courante);
1192:
1193: if (instruction_majuscule == NULL)
1194: {
1195: free((*s_etat_processus).instruction_courante);
1196: return(d_erreur);
1197: }
1198:
1199: /*
1200: * Traitement de la pile système par les
1201: * différentes instructions.
1202: */
1203:
1204: if ((strcmp(instruction_majuscule, "IF") == 0) ||
1205: (strcmp(instruction_majuscule, "IFERR") == 0) ||
1206: (strcmp(instruction_majuscule, "DO") == 0) ||
1207: (strcmp(instruction_majuscule, "WHILE") == 0) ||
1208: (strcmp(instruction_majuscule, "FOR") == 0) ||
1209: (strcmp(instruction_majuscule, "FORALL") == 0)
1210: ||
1211: (strcmp(instruction_majuscule, "START") == 0) ||
1212: (strcmp(instruction_majuscule, "SELECT") == 0)
1213: ||
1214: (strcmp(instruction_majuscule, "CRITICAL") == 0)
1215: || (strcmp(instruction_majuscule, "CASE") == 0)
1216: || (strcmp(instruction_majuscule, "<<") == 0))
1217: {
1218: if (strcmp(instruction_majuscule, "<<") == 0)
1219: {
1220: analyse(s_etat_processus, NULL);
1221: }
1222: else if ((strcmp(instruction_majuscule, "FOR") == 0)
1223: || (strcmp(instruction_majuscule, "FORALL")
1224: == 0) || (strcmp(instruction_majuscule,
1225: "START") == 0))
1226: {
1227: empilement_pile_systeme(s_etat_processus);
1228:
1229: if ((*s_etat_processus).erreur_systeme != d_es)
1230: {
1231: return(d_erreur);
1232: }
1233:
1234: (*(*s_etat_processus).l_base_pile_systeme)
1235: .type_cloture = 'L';
1236: }
1237: else
1238: {
1239: empilement_pile_systeme(s_etat_processus);
1240:
1241: if ((*s_etat_processus).erreur_systeme != d_es)
1242: {
1243: return(d_erreur);
1244: }
1245: }
1246: }
1247: else if ((strcmp(instruction_majuscule, "END") == 0) ||
1248: (strcmp(instruction_majuscule, "NEXT") == 0) ||
1249: (strcmp(instruction_majuscule, "STEP") == 0) ||
1250: (strcmp(instruction_majuscule, ">>") == 0))
1251: {
1252: if (strcmp(instruction_majuscule, ">>") == 0)
1253: {
1254: analyse(s_etat_processus, NULL);
1255:
1256: if ((*(*s_etat_processus).l_base_pile_systeme)
1257: .origine_routine_evaluation == 'Y')
1258: {
1259: free(instruction_majuscule);
1260: free((*s_etat_processus)
1261: .instruction_courante);
1262:
1263: (*s_etat_processus).instruction_courante =
1264: tampon;
1265:
1266: return(d_absence_erreur);
1267: }
1268: }
1269: else if (((strcmp(instruction_majuscule, "NEXT")
1270: == 0) || (strcmp(instruction_majuscule,
1271: "STEP") == 0)) && ((*(*s_etat_processus)
1272: .l_base_pile_systeme).type_cloture != 'L'))
1273: {
1274: /*
1275: * Libération des compteurs de boucle.
1276: */
1277:
1278: presence_compteur = (((*(*s_etat_processus)
1279: .l_base_pile_systeme).type_cloture
1280: == 'F') || ((*(*s_etat_processus)
1281: .l_base_pile_systeme).type_cloture
1282: == 'A')) ? d_vrai : d_faux;
1283:
1284: if (((*(*s_etat_processus).l_base_pile_systeme)
1285: .type_cloture != 'S') &&
1286: (presence_compteur == d_faux))
1287: {
1288: return(d_erreur);
1289: }
1290:
1291: if (presence_compteur == d_vrai)
1292: {
1293: if (recherche_variable(s_etat_processus,
1294: (*(*s_etat_processus)
1295: .l_base_pile_systeme).nom_variable)
1296: == d_faux)
1297: {
1298: return(d_erreur);
1299: }
1300:
1301: if ((*(*s_etat_processus)
1302: .pointeur_variable_courante).objet
1303: == NULL)
1304: {
1305: return(d_erreur);
1306: }
1307:
1308: (*s_etat_processus).niveau_courant--;
1309:
1310: if (retrait_variables_par_niveau(
1311: s_etat_processus) == d_erreur)
1312: {
1313: return(d_erreur);
1314: }
1315: }
1316:
1317: depilement_pile_systeme(s_etat_processus);
1318:
1319: if ((*s_etat_processus).erreur_systeme != d_es)
1320: {
1321: return(d_erreur);
1322: }
1323: }
1324: else
1325: {
1326: // Traitement spécifique pour la fin
1327: // d'une section critique
1328:
1329: if ((*s_etat_processus).l_base_pile_systeme
1330: == NULL)
1331: {
1332: (*s_etat_processus).erreur_systeme =
1333: d_es_processus;
1334: return(d_erreur);
1335: }
1336:
1337: if ((*(*s_etat_processus).l_base_pile_systeme)
1338: .type_cloture == 'Q')
1339: {
1340: if (pthread_mutex_unlock(
1341: &mutex_sections_critiques) != 0)
1342: {
1343: (*s_etat_processus).erreur_systeme =
1344: d_es_processus;
1345: return(d_erreur);
1346: }
1347:
1348: (*s_etat_processus).sections_critiques--;
1349: }
1350:
1351: depilement_pile_systeme(s_etat_processus);
1352:
1353: if ((*s_etat_processus).erreur_systeme != d_es)
1354: {
1355: return(d_erreur);
1356: }
1357: }
1358: }
1359:
1360: free(instruction_majuscule);
1361: }
1362:
1363: free((*s_etat_processus).instruction_courante);
1364: }
1365:
1366: drapeau_then = d_faux;
1367: niveau = 0;
1368:
1369: do
1370: {
1371: erreur = recherche_instruction_suivante(s_etat_processus);
1372:
1373: if (erreur == d_erreur)
1374: {
1375: return(d_erreur);
1376: }
1377:
1378: instruction_majuscule = conversion_majuscule(
1379: (*s_etat_processus).instruction_courante);
1380:
1381: if (instruction_majuscule == NULL)
1382: {
1383: return(d_erreur);
1384: }
1385:
1386: if ((strcmp(instruction_majuscule, "IF") == 0) ||
1387: (strcmp(instruction_majuscule, "IFERR") == 0) ||
1388: (strcmp(instruction_majuscule, "DO") == 0) ||
1389: (strcmp(instruction_majuscule, "WHILE") == 0) ||
1390: (strcmp(instruction_majuscule, "FOR") == 0) ||
1391: (strcmp(instruction_majuscule, "FORALL") == 0) ||
1392: (strcmp(instruction_majuscule, "START") == 0) ||
1393: (strcmp(instruction_majuscule, "SELECT") == 0)
1394: || (strcmp(instruction_majuscule, "CRITICAL") == 0)
1395: || (strcmp(instruction_majuscule, "CASE") == 0)
1396: || (strcmp(instruction_majuscule, "<<") == 0))
1397: {
1398: niveau++;
1399: }
1400: else if ((strcmp(instruction_majuscule, "END") == 0) ||
1401: (strcmp(instruction_majuscule, "NEXT") == 0) ||
1402: (strcmp(instruction_majuscule, "STEP") == 0) ||
1403: (strcmp(instruction_majuscule, ">>") == 0))
1404: {
1405: niveau--;
1406: }
1407:
1408: drapeau_then = ((strcmp(instruction_majuscule, "THEN") == 0)
1409: && (niveau == 0)) ? d_vrai : d_faux;
1410:
1411: free(instruction_majuscule);
1412: free((*s_etat_processus).instruction_courante);
1413: } while(drapeau_then == d_faux);
1414:
1415: (*s_etat_processus).position_courante -= 5;
1416: (*s_etat_processus).instruction_courante = tampon;
1417: (*(*s_etat_processus).l_base_pile_systeme).clause = 'X';
1418:
1419: erreur = d_absence_erreur;
1420: (*s_etat_processus).exception = d_ep;
1421: (*s_etat_processus).erreur_execution = d_ex;
1422: }
1423: }
1424: else
1425: {
1426: drapeau_fin = d_faux;
1427: }
1428:
1429: if (erreur == d_absence_erreur)
1430: {
1431: free((*s_etat_processus).instruction_courante);
1432: }
1433: } while((erreur == d_absence_erreur) &&
1434: ((*s_etat_processus).position_courante <
1435: (*s_etat_processus).longueur_definitions_chainees) &&
1436: (drapeau_fin == d_faux) &&
1437: ((*s_etat_processus).retour_routine_evaluation == 'N'));
1438:
1439: /*
1440: --------------------------------------------------------------------------------
1441: Messages d'erreur à afficher le cas échéant
1442: --------------------------------------------------------------------------------
1443: */
1444:
1445: if ((erreur != d_absence_erreur) && ((*s_etat_processus)
1446: .invalidation_message_erreur == d_faux))
1447: {
1448: if (test_cfsf(s_etat_processus, 31) == d_vrai)
1449: {
1450: l_element_courant = (*s_etat_processus).l_base_pile_last;
1451:
1452: while(l_element_courant != NULL)
1453: {
1454: if ((s_objet = copie_objet(s_etat_processus,
1455: (*l_element_courant).donnee, 'P')) == NULL)
1456: {
1457: (*s_etat_processus).erreur_systeme =
1458: d_es_allocation_memoire;
1459: return(d_erreur);
1460: }
1461:
1462: if (empilement(s_etat_processus, &((*s_etat_processus)
1463: .l_base_pile), s_objet) == d_erreur)
1464: {
1465: return(d_erreur);
1466: }
1467:
1468: l_element_courant = (*l_element_courant).suivant;
1469: }
1470: }
1471:
1472: if (test_cfsf(s_etat_processus, 51) == d_faux)
1473: {
1474: printf("%s", ds_beep);
1475: }
1476:
1477: if ((message = messages(s_etat_processus)) == NULL)
1478: {
1479: return(d_erreur);
1480: }
1481:
1482: printf("%s [%d]\n", message, (int) getpid());
1483:
1484: free(message);
1485: free((*s_etat_processus).instruction_courante);
1486:
1487: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1488: {
1489: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1490: rpl_sigalrm);
1491: }
1492: else
1493: {
1494: (*s_etat_processus).var_volatile_alarme = -1;
1495: }
1496:
1497: return(d_erreur);
1498: }
1499:
1500: return(d_absence_erreur);
1501: }
1502:
1503: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>