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