1: /*
2: ================================================================================
3: RPL/2 (R) version 4.0.20
4: Copyright (C) 1989-2010 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:
52: static logical1 completion_valide = d_faux;
53:
54: struct sigaction action;
55: struct sigaction action_defaut;
56: struct sigaction action_defaut2;
57:
58: unsigned char *instruction_majuscule;
59: unsigned char *ligne;
60: unsigned char *message;
61: unsigned char *registre;
62: unsigned char *tampon;
63: unsigned char tampon_retour;
64: unsigned char *t_ligne;
65:
66: unsigned long i;
67: unsigned long j;
68: unsigned long niveau;
69: unsigned long position_courante;
70:
71: (*s_etat_processus).retour_routine_evaluation = 'N';
72:
73: if ((*s_etat_processus).debug == d_vrai)
74: if (((*s_etat_processus).type_debug &
75: d_debug_appels_fonctions) != 0)
76: {
77: if ((*s_etat_processus).niveau_recursivite != 0)
78: {
79: if ((*s_etat_processus).langue == 'F')
80: {
81: printf("[%d] Exécution récursive de niveau %lu\n",
82: (int) getpid(), (*s_etat_processus).niveau_recursivite);
83: }
84: else
85: {
86: printf("[%d] %lu level recursive execution\n",
87: (int) getpid(), (*s_etat_processus).niveau_recursivite);
88: }
89: }
90: else
91: {
92: if ((*s_etat_processus).langue == 'F')
93: {
94: printf("[%d] Exécution\n", (int) getpid());
95: }
96: else
97: {
98: printf("[%d] Execution\n", (int) getpid());
99: }
100: }
101:
102: fflush(stdout);
103: }
104:
105: /*
106: --------------------------------------------------------------------------------
107: Boucle de l'interprète RPL/2
108: On boucle tant qu'on n'a pas une bonne raison de sortir...
109: --------------------------------------------------------------------------------
110: */
111:
112: i = 0;
113: j = 0;
114:
115: do
116: {
117: drapeau_appel_definition = d_faux;
118:
119: /*
120: --------------------------------------------------------------------------------
121: Recherche de l'instruction suivante dans les définitions chaînées
122: --------------------------------------------------------------------------------
123: */
124:
125: if ((erreur = recherche_instruction_suivante(s_etat_processus))
126: == d_erreur)
127: {
128: return(d_erreur);
129: }
130:
131: if (((*s_etat_processus).debug_programme == d_vrai) &&
132: ((*s_etat_processus).niveau_recursivite == 0))
133: {
134: /*
135: * Traitement de la commande HALT (debug)
136: */
137:
138: action.sa_handler = SIG_IGN;
139: action.sa_flags = SA_NODEFER | SA_ONSTACK;
140:
141: (*s_etat_processus).execution_pas_suivant = d_faux;
142: (*s_etat_processus).traitement_instruction_halt = d_vrai;
143:
144: if (completion_valide == d_faux)
145: {
146: initialisation_completion();
147: completion_valide = d_vrai;
148: }
149:
150: while((*s_etat_processus).execution_pas_suivant == d_faux)
151: {
152: if ((*s_etat_processus).hauteur_pile_operationnelle != 0)
153: {
154: fprintf(stdout, "\n");
155: }
156:
157: affichage_pile(s_etat_processus, (*s_etat_processus)
158: .l_base_pile, 1);
159:
160: if ((*s_etat_processus).mode_interactif == 'N')
161: {
162: printf("[%d] Instruction : %s\n", (int) getpid(),
163: (*s_etat_processus).instruction_courante);
164: fflush(stdout);
165: }
166:
167: if (sigaction(SIGINT, &action, &action_defaut) != 0)
168: {
169: (*s_etat_processus).erreur_systeme = d_es_signal;
170: return(d_erreur);
171: }
172:
173: if (sigaction(SIGTSTP, &action, &action_defaut2) != 0)
174: {
175: (*s_etat_processus).erreur_systeme = d_es_signal;
176: return(d_erreur);
177: }
178:
179: (*s_etat_processus).var_volatile_requete_arret = 0;
180: (*s_etat_processus).var_volatile_requete_arret2 = 0;
181:
182: flockfile(stdin);
183: flockfile(stdout);
184:
185: ligne = readline("RPL/2> ");
186:
187: funlockfile(stdin);
188: funlockfile(stdout);
189:
190: if ((*s_etat_processus).var_volatile_requete_arret != 0)
191: {
192: (*s_etat_processus).requete_arret = 'Y';
193: break;
194: }
195:
196: if (ligne != NULL)
197: {
198: if ((t_ligne = transliteration(s_etat_processus, ligne,
199: (*s_etat_processus).localisation, d_locale))
200: == NULL)
201: {
202: free((*s_etat_processus).instruction_courante);
203: return(d_erreur);
204: }
205:
206: free(ligne);
207: ligne = t_ligne;
208:
209: if ((ligne = compactage(ligne)) == NULL)
210: {
211: (*s_etat_processus).erreur_systeme =
212: d_es_allocation_memoire;
213: return(d_erreur);
214: }
215: }
216:
217: if (sigaction(SIGINT, &action_defaut, NULL) != 0)
218: {
219: (*s_etat_processus).erreur_systeme = d_es_signal;
220: return(d_erreur);
221: }
222:
223: if (sigaction(SIGTSTP, &action_defaut2, NULL) != 0)
224: {
225: (*s_etat_processus).erreur_systeme = d_es_signal;
226: return(d_erreur);
227: }
228:
229: if (ligne == NULL)
230: {
231: if ((ligne = (unsigned char *) malloc(6 *
232: sizeof(unsigned char))) == NULL)
233: {
234: (*s_etat_processus).erreur_systeme =
235: d_es_allocation_memoire;
236: return(d_erreur);
237: }
238:
239: sprintf(ligne, "abort");
240: fprintf(stdout, "%s\n", ligne);
241: }
242: else if (((*ligne) == d_code_fin_chaine) &&
243: ((*s_etat_processus).l_base_pile != NULL))
244: {
245: free(ligne);
246:
247: if ((ligne = (unsigned char *) malloc(4 *
248: sizeof(unsigned char))) == NULL)
249: {
250: (*s_etat_processus).erreur_systeme =
251: d_es_allocation_memoire;
252: return(d_erreur);
253: }
254:
255: sprintf(ligne, "dup");
256: }
257:
258: add_history(ligne);
259: stifle_history(ds_longueur_historique);
260:
261: position_courante = (*s_etat_processus).position_courante;
262: tampon = (*s_etat_processus).definitions_chainees;
263: registre = (*s_etat_processus).instruction_courante;
264: (*s_etat_processus).definitions_chainees = ligne;
265:
266: if (analyse_syntaxique(s_etat_processus) == d_absence_erreur)
267: {
268: (*s_etat_processus).instruction_courante = registre;
269: (*s_etat_processus).position_courante = position_courante;
270: (*s_etat_processus).definitions_chainees = tampon;
271:
272: if ((tampon = (unsigned char *) malloc((strlen(ligne) + 7) *
273: sizeof(unsigned char))) == NULL)
274: {
275: (*s_etat_processus).erreur_systeme =
276: d_es_allocation_memoire;
277: return(d_erreur);
278: }
279:
280: sprintf(tampon, "<< %s >>", ligne);
281:
282: free(ligne);
283: ligne = tampon;
284:
285: tampon = (*s_etat_processus).instruction_courante;
286: (*s_etat_processus).instruction_courante = ligne;
287:
288: recherche_type(s_etat_processus);
289:
290: (*s_etat_processus).instruction_courante = tampon;
291:
292: if ((((*s_etat_processus).erreur_execution != d_ex) ||
293: ((*s_etat_processus).erreur_systeme != d_es)) &&
294: ((*s_etat_processus).invalidation_message_erreur
295: == d_faux))
296: {
297: if ((*s_etat_processus).erreur_execution != d_ex)
298: {
299: (*s_etat_processus).erreur_scrutation = d_vrai;
300: }
301:
302: if (test_cfsf(s_etat_processus, 51) == d_faux)
303: {
304: printf("%s", ds_beep);
305: }
306:
307: if ((message = messages(s_etat_processus)) == NULL)
308: {
309: free((*s_etat_processus).instruction_courante);
310: return(d_erreur);
311: }
312:
313: printf("%s [%d]\n", message, (int) getpid());
314:
315: free(message);
316:
317: (*s_etat_processus).erreur_execution = d_ex;
318:
319: if ((*s_etat_processus).erreur_systeme != d_es)
320: {
321: return(d_erreur);
322: }
323: }
324: else
325: {
326: tampon_retour = (*(*s_etat_processus)
327: .l_base_pile_systeme).retour_definition;
328: (*(*s_etat_processus).l_base_pile_systeme)
329: .retour_definition = 'Y';
330:
331: if (depilement(s_etat_processus, &((*s_etat_processus)
332: .l_base_pile), &s_objet) == d_erreur)
333: {
334: if (test_cfsf(s_etat_processus, 51) == d_faux)
335: {
336: printf("%s", ds_beep);
337: }
338:
339: if ((*s_etat_processus).langue == 'F')
340: {
341: printf("+++Erreur : Défaut d'argument\n");
342: }
343: else
344: {
345: printf("+++Error : Too few arguments\n");
346: }
347:
348: (*(*s_etat_processus).l_base_pile_systeme)
349: .retour_definition = tampon_retour;
350:
351: fflush(stdout);
352: }
353: else if (evaluation(s_etat_processus, s_objet, 'I') ==
354: d_erreur)
355: {
356: (*(*s_etat_processus).l_base_pile_systeme)
357: .retour_definition = tampon_retour;
358:
359: if ((*s_etat_processus).erreur_systeme != d_es)
360: {
361: if (test_cfsf(s_etat_processus, 51) == d_faux)
362: {
363: printf("%s", ds_beep);
364: }
365:
366: if ((message = messages(s_etat_processus))
367: == NULL)
368: {
369: free((*s_etat_processus)
370: .instruction_courante);
371: return(d_erreur);
372: }
373:
374: printf("%s [%d]\n", message, (int) getpid());
375:
376: free(message);
377: free((*s_etat_processus).instruction_courante);
378: return(d_erreur);
379: }
380: else if ((*s_etat_processus)
381: .invalidation_message_erreur == d_faux)
382: {
383: (*s_etat_processus).erreur_execution =
384: (*s_etat_processus)
385: .derniere_erreur_evaluation;
386:
387: if (test_cfsf(s_etat_processus, 51) == d_faux)
388: {
389: printf("%s", ds_beep);
390: }
391:
392: if ((message = messages(s_etat_processus))
393: == NULL)
394: {
395: free((*s_etat_processus)
396: .instruction_courante);
397: return(d_erreur);
398: }
399:
400: printf("%s [%d]\n", message, (int) getpid());
401: free(message);
402:
403: if (test_cfsf(s_etat_processus, 31) == d_vrai)
404: {
405: l_element_courant = (*s_etat_processus)
406: .l_base_pile_last;
407:
408: while(l_element_courant != NULL)
409: {
410: if ((s_sous_objet = copie_objet(
411: s_etat_processus,
412: (*l_element_courant).donnee,
413: 'P')) == NULL)
414: {
415: (*s_etat_processus).erreur_systeme =
416: d_es_allocation_memoire;
417: return(d_erreur);
418: }
419:
420: if (empilement(s_etat_processus,
421: &((*s_etat_processus)
422: .l_base_pile),
423: s_sous_objet) == d_erreur)
424: {
425: return(d_erreur);
426: }
427:
428: l_element_courant = (*l_element_courant)
429: .suivant;
430: }
431: }
432:
433: (*s_etat_processus).erreur_execution = d_ex;
434: (*s_etat_processus).exception = d_ep;
435: }
436:
437: liberation(s_etat_processus, s_objet);
438: }
439: else
440: {
441: liberation(s_etat_processus, s_objet);
442: }
443:
444: (*(*s_etat_processus).l_base_pile_systeme)
445: .retour_definition = tampon_retour;
446: }
447: }
448: else if ((*s_etat_processus).invalidation_message_erreur
449: == d_faux)
450: {
451: (*s_etat_processus).instruction_courante = registre;
452: (*s_etat_processus).position_courante = position_courante;
453: (*s_etat_processus).definitions_chainees = tampon;
454:
455: if (test_cfsf(s_etat_processus, 51) == d_faux)
456: {
457: printf("%s", ds_beep);
458: }
459:
460: if ((message = messages(s_etat_processus)) == NULL)
461: {
462: free((*s_etat_processus).instruction_courante);
463: free(ligne);
464: return(d_erreur);
465: }
466:
467: free(message);
468:
469: if ((*s_etat_processus).langue == 'F')
470: {
471: printf("+++Erreur : Erreur de syntaxe\n");
472: }
473: else
474: {
475: printf("+++Error : Syntax error\n");
476: }
477:
478: fflush(stdout);
479: }
480:
481: free(ligne);
482: }
483:
484: (*s_etat_processus).traitement_instruction_halt = d_faux;
485: }
486:
487: if ((*s_etat_processus).debug == d_vrai)
488: if (((*s_etat_processus).type_debug &
489: d_debug_fonctions_intrinseques) != 0)
490: {
491: if ((*s_etat_processus).langue == 'F')
492: {
493: printf("[%d] Instruction %s\n",
494: (int) getpid(),
495: (*s_etat_processus).instruction_courante);
496: }
497: else
498: {
499: printf("[%d] %s instruction\n",
500: (int) getpid(),
501: (*s_etat_processus).instruction_courante);
502: }
503:
504: fflush(stdout);
505: }
506:
507: /*
508: --------------------------------------------------------------------------------
509: Dans le cas où une instruction est retournée, celle-ci est évaluée. Dans le
510: cas contraire, l'interprète renvoie un message d'erreur et s'interrompt.
511: --------------------------------------------------------------------------------
512: */
513:
514: if (erreur == d_absence_erreur)
515: {
516:
517: /*
518: --------------------------------------------------------------------------------
519: Scrutation des mots clef du langage RPL/2 et exécution le cas échéant
520: de l'action associée.
521: --------------------------------------------------------------------------------
522: */
523:
524: analyse(s_etat_processus, NULL);
525:
526: if ((*s_etat_processus).traitement_cycle_exit != 'N')
527: {
528: switch((*s_etat_processus).traitement_cycle_exit)
529: {
530: case 'C' :
531: {
532: instruction_cycle(s_etat_processus);
533: break;
534: }
535:
536: case 'E' :
537: {
538: instruction_exit(s_etat_processus);
539: break;
540: }
541: }
542: }
543:
544: if ((*s_etat_processus).instruction_valide == 'N')
545: {
546:
547: /*
548: --------------------------------------------------------------------------------
549: L'instruction ne correspond pas à l'un des mots clef du langage RPL/2.
550: --------------------------------------------------------------------------------
551: */
552:
553: if ((recherche_variable(s_etat_processus,
554: (*s_etat_processus).instruction_courante) ==
555: d_vrai) && ((*s_etat_processus)
556: .autorisation_evaluation_nom == 'Y'))
557: {
558: if (((*s_etat_processus).s_liste_variables
559: [(*s_etat_processus)
560: .position_variable_courante]).objet == NULL)
561: {
562:
563: /*
564: --------------------------------------------------------------------------------
565: L'instruction est une variable partagée
566: --------------------------------------------------------------------------------
567: */
568:
569: if ((*s_etat_processus).debug == d_vrai)
570: if (((*s_etat_processus).type_debug &
571: d_debug_variables) != 0)
572: {
573: if ((*s_etat_processus).langue == 'F')
574: {
575: printf("[%d] Empilement de la variable "
576: "partagée %s de type %d\n",
577: (int) getpid(),
578: (*s_etat_processus)
579: .instruction_courante,
580: (*((*s_etat_processus).s_liste_variables
581: [(*s_etat_processus)
582: .position_variable_courante]).objet)
583: .type);
584: }
585: else
586: {
587: printf("[%d] Pushing %s as %d type shared "
588: "variable \n", (int) getpid(),
589: (*s_etat_processus)
590: .instruction_courante,
591: (*((*s_etat_processus).s_liste_variables
592: [(*s_etat_processus)
593: .position_variable_courante]).objet)
594: .type);
595: }
596:
597: fflush(stdout);
598: }
599:
600: if (pthread_mutex_lock(&((*(*s_etat_processus)
601: .s_liste_variables_partagees).mutex)) != 0)
602: {
603: (*s_etat_processus).erreur_systeme =
604: d_es_processus;
605: return(d_erreur);
606: }
607:
608: if (recherche_variable_partagee(s_etat_processus,
609: ((*s_etat_processus).s_liste_variables
610: [(*s_etat_processus)
611: .position_variable_courante]).nom,
612: ((*s_etat_processus).s_liste_variables
613: [(*s_etat_processus)
614: .position_variable_courante])
615: .variable_partagee, 'P') == d_vrai)
616: {
617: // La variable existe.
618:
619: if ((s_objet = copie_objet(s_etat_processus,
620: (*(*s_etat_processus)
621: .s_liste_variables_partagees)
622: .table[(*(*s_etat_processus)
623: .s_liste_variables_partagees)
624: .position_variable].objet, 'P'))
625: == NULL)
626: {
627: (*s_etat_processus).erreur_systeme =
628: d_es_allocation_memoire;
629: return(d_erreur);
630: }
631:
632: if (pthread_mutex_unlock(&((*(*s_etat_processus)
633: .s_liste_variables_partagees).mutex))
634: != 0)
635: {
636: (*s_etat_processus).erreur_systeme =
637: d_es_processus;
638: return(d_erreur);
639: }
640:
641: if (empilement(s_etat_processus,
642: &((*s_etat_processus).l_base_pile),
643: s_objet) == d_erreur)
644: {
645: (*s_etat_processus).erreur_systeme =
646: d_es_allocation_memoire;
647: return(d_erreur);
648: }
649: }
650: else
651: {
652: // La variable n'existe plus.
653:
654: (*s_etat_processus).erreur_systeme = d_es;
655:
656: if (pthread_mutex_unlock(&((*(*s_etat_processus)
657: .s_liste_variables_partagees).mutex))
658: != 0)
659: {
660: (*s_etat_processus).erreur_systeme =
661: d_es_processus;
662: return(d_erreur);
663: }
664:
665: recherche_type(s_etat_processus);
666: }
667: }
668:
669: /*
670: --------------------------------------------------------------------------------
671: L'instruction est une variable automatique (évaluation lors de l'empilement).
672: --------------------------------------------------------------------------------
673: */
674:
675: else if ((*((*s_etat_processus).s_liste_variables
676: [(*s_etat_processus).position_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).s_liste_variables
746: [(*s_etat_processus)
747: .position_variable_courante]
748: .objet)).objet)));
749:
750: drapeau_appel_definition = d_vrai;
751: }
752: }
753: else
754: {
755: if ((*s_etat_processus).debug == d_vrai)
756: if (((*s_etat_processus).type_debug &
757: d_debug_variables) != 0)
758: {
759: if ((*s_etat_processus).langue == 'F')
760: {
761: printf("[%d] Empilement de la variable "
762: "%s de type %d\n",
763: (int) getpid(),
764: (*s_etat_processus)
765: .instruction_courante,
766: (*((*s_etat_processus).s_liste_variables
767: [(*s_etat_processus)
768: .position_variable_courante]).objet)
769: .type);
770: }
771: else
772: {
773: printf("[%d] Pushing %s as %d type variable "
774: "\n", (int) getpid(),
775: (*s_etat_processus)
776: .instruction_courante,
777: (*((*s_etat_processus).s_liste_variables
778: [(*s_etat_processus)
779: .position_variable_courante]).objet)
780: .type);
781: }
782:
783: fflush(stdout);
784: }
785:
786: if ((s_objet = copie_objet(s_etat_processus,
787: ((*s_etat_processus)
788: .s_liste_variables[(*s_etat_processus)
789: .position_variable_courante]).objet, 'P'))
790: == NULL)
791: {
792: (*s_etat_processus).erreur_systeme =
793: d_es_allocation_memoire;
794: return(d_erreur);
795: }
796:
797: if (empilement(s_etat_processus,
798: &((*s_etat_processus).l_base_pile),
799: s_objet) == d_erreur)
800: {
801: (*s_etat_processus).erreur_systeme =
802: d_es_allocation_memoire;
803: return(d_erreur);
804: }
805: }
806: }
807: else
808: {
809:
810: /*
811: --------------------------------------------------------------------------------
812: L'instruction est une donnée à empiler.
813: --------------------------------------------------------------------------------
814: */
815:
816: (*s_etat_processus).erreur_systeme = d_es;
817: recherche_type(s_etat_processus);
818:
819: if ((*s_etat_processus).autorisation_nom_implicite == 'N')
820: {
821: if ((*s_etat_processus).l_base_pile == NULL)
822: {
823: (*s_etat_processus).erreur_execution =
824: d_ex_manque_argument;
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).s_liste_variables
1171: [(*s_etat_processus)
1172: .position_variable_courante]).objet == NULL)
1173: {
1174: // Variable partagée
1175: }
1176: else if ((*((*s_etat_processus).s_liste_variables
1177: [(*s_etat_processus)
1178: .position_variable_courante]).objet).type ==
1179: ADR)
1180: {
1181: empilement_pile_systeme(s_etat_processus);
1182:
1183: if ((*s_etat_processus).erreur_systeme != d_es)
1184: {
1185: free((*s_etat_processus).instruction_courante);
1186: return(d_erreur);
1187: }
1188:
1189: (*(*s_etat_processus).l_base_pile_systeme)
1190: .adresse_retour = (*s_etat_processus)
1191: .position_courante;
1192:
1193: (*(*s_etat_processus).l_base_pile_systeme)
1194: .retour_definition = 'Y';
1195:
1196: (*(*s_etat_processus).l_base_pile_systeme)
1197: .niveau_courant = (*s_etat_processus)
1198: .niveau_courant;
1199:
1200: (*s_etat_processus).position_courante =
1201: (*((unsigned long *)
1202: ((*((*s_etat_processus).s_liste_variables
1203: [(*s_etat_processus)
1204: .position_variable_courante]
1205: .objet)).objet)));
1206:
1207: (*s_etat_processus)
1208: .autorisation_empilement_programme = 'N';
1209: }
1210: }
1211: else
1212: {
1213: (*s_etat_processus).erreur_systeme = d_es;
1214: instruction_majuscule = conversion_majuscule(
1215: (*s_etat_processus).instruction_courante);
1216:
1217: if (instruction_majuscule == NULL)
1218: {
1219: free((*s_etat_processus).instruction_courante);
1220: return(d_erreur);
1221: }
1222:
1223: /*
1224: * Traitement de la pile système par les
1225: * différentes instructions.
1226: */
1227:
1228: if ((strcmp(instruction_majuscule, "IF") == 0) ||
1229: (strcmp(instruction_majuscule, "IFERR") == 0) ||
1230: (strcmp(instruction_majuscule, "DO") == 0) ||
1231: (strcmp(instruction_majuscule, "WHILE") == 0) ||
1232: (strcmp(instruction_majuscule, "FOR") == 0) ||
1233: (strcmp(instruction_majuscule, "START") == 0) ||
1234: (strcmp(instruction_majuscule, "SELECT") == 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
1243: {
1244: empilement_pile_systeme(s_etat_processus);
1245:
1246: if ((*s_etat_processus).erreur_systeme != d_es)
1247: {
1248: return(d_erreur);
1249: }
1250: }
1251: }
1252: else if ((strcmp(instruction_majuscule, "END") == 0) ||
1253: (strcmp(instruction_majuscule, "NEXT") == 0) ||
1254: (strcmp(instruction_majuscule, "STEP") == 0) ||
1255: (strcmp(instruction_majuscule, ">>") == 0))
1256: {
1257: if (strcmp(instruction_majuscule, ">>") == 0)
1258: {
1259: analyse(s_etat_processus, NULL);
1260:
1261: if ((*(*s_etat_processus).l_base_pile_systeme)
1262: .origine_routine_evaluation == 'Y')
1263: {
1264: free(instruction_majuscule);
1265: free((*s_etat_processus)
1266: .instruction_courante);
1267:
1268: (*s_etat_processus).instruction_courante =
1269: tampon;
1270:
1271: return(d_absence_erreur);
1272: }
1273: }
1274: else
1275: {
1276: depilement_pile_systeme(s_etat_processus);
1277:
1278: if ((*s_etat_processus).erreur_systeme != d_es)
1279: {
1280: return(d_erreur);
1281: }
1282: }
1283: }
1284:
1285: free(instruction_majuscule);
1286: }
1287:
1288: free((*s_etat_processus).instruction_courante);
1289: }
1290:
1291: drapeau_then = d_faux;
1292: niveau = 0;
1293:
1294: do
1295: {
1296: erreur = recherche_instruction_suivante(s_etat_processus);
1297:
1298: if (erreur == d_erreur)
1299: {
1300: return(d_erreur);
1301: }
1302:
1303: instruction_majuscule = conversion_majuscule(
1304: (*s_etat_processus).instruction_courante);
1305:
1306: if (instruction_majuscule == NULL)
1307: {
1308: return(d_erreur);
1309: }
1310:
1311: if ((strcmp(instruction_majuscule, "IF") == 0) ||
1312: (strcmp(instruction_majuscule, "IFERR") == 0) ||
1313: (strcmp(instruction_majuscule, "DO") == 0) ||
1314: (strcmp(instruction_majuscule, "WHILE") == 0) ||
1315: (strcmp(instruction_majuscule, "FOR") == 0) ||
1316: (strcmp(instruction_majuscule, "START") == 0) ||
1317: (strcmp(instruction_majuscule, "SELECT") == 0)
1318: || (strcmp(instruction_majuscule, "CASE") == 0)
1319: || (strcmp(instruction_majuscule, "<<") == 0))
1320: {
1321: niveau++;
1322: }
1323: else if ((strcmp(instruction_majuscule, "END") == 0) ||
1324: (strcmp(instruction_majuscule, "NEXT") == 0) ||
1325: (strcmp(instruction_majuscule, "STEP") == 0) ||
1326: (strcmp(instruction_majuscule, ">>") == 0))
1327: {
1328: niveau--;
1329: }
1330:
1331: drapeau_then = ((strcmp(instruction_majuscule, "THEN") == 0)
1332: && (niveau == 0)) ? d_vrai : d_faux;
1333:
1334: free(instruction_majuscule);
1335: free((*s_etat_processus).instruction_courante);
1336: } while(drapeau_then == d_faux);
1337:
1338: (*s_etat_processus).position_courante -= 5;
1339: (*s_etat_processus).instruction_courante = tampon;
1340: (*(*s_etat_processus).l_base_pile_systeme).clause = 'X';
1341:
1342: erreur = d_absence_erreur;
1343: (*s_etat_processus).exception = d_ep;
1344: (*s_etat_processus).erreur_execution = d_ex;
1345: }
1346: }
1347: else
1348: {
1349: drapeau_fin = d_faux;
1350: }
1351:
1352: if (erreur == d_absence_erreur)
1353: {
1354: free((*s_etat_processus).instruction_courante);
1355: }
1356: } while((erreur == d_absence_erreur) &&
1357: ((*s_etat_processus).position_courante <
1358: (*s_etat_processus).longueur_definitions_chainees) &&
1359: (drapeau_fin == d_faux) &&
1360: ((*s_etat_processus).retour_routine_evaluation == 'N'));
1361:
1362: /*
1363: --------------------------------------------------------------------------------
1364: Messages d'erreur à afficher le cas échéant
1365: --------------------------------------------------------------------------------
1366: */
1367:
1368: if ((erreur != d_absence_erreur) && ((*s_etat_processus)
1369: .invalidation_message_erreur == d_faux))
1370: {
1371: if (test_cfsf(s_etat_processus, 31) == d_vrai)
1372: {
1373: l_element_courant = (*s_etat_processus).l_base_pile_last;
1374:
1375: while(l_element_courant != NULL)
1376: {
1377: if ((s_objet = copie_objet(s_etat_processus,
1378: (*l_element_courant).donnee, 'P')) == NULL)
1379: {
1380: (*s_etat_processus).erreur_systeme =
1381: d_es_allocation_memoire;
1382: return(d_erreur);
1383: }
1384:
1385: if (empilement(s_etat_processus, &((*s_etat_processus)
1386: .l_base_pile), s_objet) == d_erreur)
1387: {
1388: return(d_erreur);
1389: }
1390:
1391: l_element_courant = (*l_element_courant).suivant;
1392: }
1393: }
1394:
1395: if (test_cfsf(s_etat_processus, 51) == d_faux)
1396: {
1397: printf("%s", ds_beep);
1398: }
1399:
1400: if ((message = messages(s_etat_processus)) == NULL)
1401: {
1402: return(d_erreur);
1403: }
1404:
1405: printf("%s [%d]\n", message, (int) getpid());
1406:
1407: free(message);
1408: free((*s_etat_processus).instruction_courante);
1409:
1410: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1411: {
1412: kill((*s_etat_processus).pid_processus_pere, SIGALRM);
1413: }
1414: else
1415: {
1416: (*s_etat_processus).var_volatile_alarme = -1;
1417: }
1418:
1419: return(d_erreur);
1420: }
1421:
1422: return(d_absence_erreur);
1423: }
1424:
1425: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>