--- rpl/src/instructions_b1.c 2010/01/26 15:22:45 1.1.1.1 +++ rpl/src/instructions_b1.c 2013/03/11 11:07:25 1.44 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.9 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.13 + Copyright (C) 1989-2013 Dr. BERTRAND Joël This file is part of RPL/2. @@ -20,7 +20,7 @@ */ -#include "rpl.conv.h" +#include "rpl-conv.h" /* @@ -241,11 +241,16 @@ instruction_b_vers_r(struct_processus *s void instruction_backspace(struct_processus *s_etat_processus) { - file *descripteur; + struct_descripteur_fichier *descripteur; + + int i; + int nombre_octets; integer8 position_finale; integer8 position_initiale; + integer8 saut; + logical1 guillemets_a_cheval; logical1 presence_chaine; logical1 presence_indicateur; @@ -260,6 +265,7 @@ instruction_backspace(struct_processus * struct_objet *s_objet_argument; unsigned char *tampon_lecture; + unsigned char tampon[9]; (*s_etat_processus).erreur_execution = d_ex; @@ -304,44 +310,45 @@ instruction_backspace(struct_processus * if ((*s_objet_argument).type == FCH) { /* - * Vérification des verrous + * Fichiers à accès séquentiel */ - lock.l_type = F_RDLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - lock.l_pid = getpid(); - - if ((descripteur = descripteur_fichier(s_etat_processus, - (struct_fichier *) (*s_objet_argument).objet)) == NULL) + if ((*((struct_fichier *) (*s_objet_argument).objet)).acces == 'S') { - liberation(s_etat_processus, s_objet_argument); - return; - } + /* + * Vérification des verrous + */ - if (fcntl(fileno(descripteur), F_GETLK, &lock) == -1) - { - liberation(s_etat_processus, s_objet_argument); + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + lock.l_pid = getpid(); - (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; - return; - } + if ((descripteur = descripteur_fichier(s_etat_processus, + (struct_fichier *) (*s_objet_argument).objet)) == NULL) + { + liberation(s_etat_processus, s_objet_argument); + return; + } - if (lock.l_type != F_UNLCK) - { - liberation(s_etat_processus, s_objet_argument); + if (fcntl(fileno((*descripteur).descripteur_c), F_GETLK, &lock) + == -1) + { + liberation(s_etat_processus, s_objet_argument); - (*s_etat_processus).erreur_execution = - d_ex_fichier_verrouille; - return; - } + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return; + } - if ((*((struct_fichier *) (*s_objet_argument).objet)).acces == 'S') - { - /* - * Fichiers à accès séquentiel - */ + if (lock.l_type != F_UNLCK) + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_execution = + d_ex_fichier_verrouille; + return; + } if ((*((struct_fichier *) (*s_objet_argument).objet)).binaire == 'N') @@ -350,7 +357,8 @@ instruction_backspace(struct_processus * * Fichiers formatés */ - if ((position_finale = ftell(descripteur)) == -1) + if ((position_finale = ftell((*descripteur).descripteur_c)) + == -1) { liberation(s_etat_processus, s_objet_argument); @@ -381,7 +389,8 @@ instruction_backspace(struct_processus * longueur_effective = longueur_questure; } - if (fseek(descripteur, position_initiale, SEEK_SET) != 0) + if (fseek((*descripteur).descripteur_c, position_initiale, + SEEK_SET) != 0) { (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; @@ -390,7 +399,7 @@ instruction_backspace(struct_processus * longueur_effective = fread(tampon_lecture, (size_t) sizeof(unsigned char), longueur_effective, - descripteur); + (*descripteur).descripteur_c); pointeur = longueur_effective - 1; presence_indicateur = d_faux; @@ -416,7 +425,7 @@ instruction_backspace(struct_processus * * Le début du fichier est atteint. */ - if (fseek(descripteur, 0, SEEK_SET) != 0) + if (fseek((*descripteur).descripteur_c, 0, SEEK_SET) != 0) { liberation(s_etat_processus, s_objet_argument); free(tampon_lecture); @@ -463,7 +472,8 @@ instruction_backspace(struct_processus * position_finale--; } - if (fseek(descripteur, position_initiale, SEEK_SET) != 0) + if (fseek((*descripteur).descripteur_c, position_initiale, + SEEK_SET) != 0) { (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; @@ -472,17 +482,36 @@ instruction_backspace(struct_processus * longueur_effective = fread(tampon_lecture, (size_t) sizeof(unsigned char), longueur_effective, - descripteur); + (*descripteur).descripteur_c); pointeur = longueur_effective - 1; presence_indicateur = d_faux; + guillemets_a_cheval = d_faux; - while((pointeur >= 0) && (presence_indicateur == d_faux)) + while((pointeur >= 0) && (presence_indicateur == d_faux) + && (guillemets_a_cheval == d_faux)) { if (tampon_lecture[pointeur] == '"') { - presence_chaine = (presence_chaine == d_vrai) - ? d_faux : d_vrai; + if (pointeur > 0) + { + // On n'est pas au début du buffer, on regarde + // si les guillemets sont échappés. + + if (tampon_lecture[pointeur - 1] != '\\') + { + presence_chaine = (presence_chaine + == d_vrai) ? d_faux : d_vrai; + } + } + else + { + // On est au début du buffer. Un guillemet + // peut-être échappé par le dernier caractère + // du buffer précédent. + + guillemets_a_cheval = d_vrai; + } } else { @@ -496,14 +525,17 @@ instruction_backspace(struct_processus * } } - if (niveau == 0) + if (guillemets_a_cheval == d_faux) { - presence_indicateur = d_vrai; - } - else - { - position_finale--; - pointeur--; + if (niveau == 0) + { + presence_indicateur = d_vrai; + } + else + { + position_finale--; + pointeur--; + } } } } while((longueur_effective == longueur_questure) && @@ -519,7 +551,8 @@ instruction_backspace(struct_processus * return; } - if (fseek(descripteur, position_finale, SEEK_SET) != 0) + if (fseek((*descripteur).descripteur_c, position_finale, + SEEK_SET) != 0) { liberation(s_etat_processus, s_objet_argument); free(tampon_lecture); @@ -535,6 +568,141 @@ instruction_backspace(struct_processus * /* * Fichiers non formatés */ + + /* + Chaque enregistrement est terminé par un champ + * indiquant la longueur totale de cet enregistrement. + * + * XXXXXXX0 longueur sur 7 bits + * XXXX0011 XXXXXXXX XXXX0011 longueur sur 16 bits + * LSB(1/2) MSB LSB(2/2) + * XXXX0101 XXXXXXXX XXXXXXXX XXXX0101 longueur sur 24 bits + * XXXX0111 XXXXXXXX XXXXXXXX XXXXXXXX + * XXXX0111 longueur sur 32 bits + * XXXX1001 XXXXXXXX XXXXXXXX XXXXXXXX + * XXXXXXXX XXXX1001 longueur sur 40 bits + * XXXX1011 XXXXXXXX XXXXXXXX XXXXXXXX + * XXXXXXXX XXXXXXXX XXXX1011 longueur sur 48 bits + * XXXX1101 XXXXXXXX XXXXXXXX XXXXXXXX + * XXXXXXXX XXXXXXXX XXXXXXXX + * XXXX1101 longueur sur 56 bits + * XXXX1111 XXXXXXXX XXXXXXXX XXXXXXXX + * XXXXXXXX XXXXXXXX XXXXXXXX + * XXXXXXXX XXXX1111 longueur sur 64 bits + */ + + if ((position_finale = ftell((*descripteur).descripteur_c)) + == -1) + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return; + } + + // Lecture du premier octet. Le pointeur de lecture se + // trouve après l'opération à sa position initiale. + + if (position_finale == 0) + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_execution = + d_ex_debut_de_fichier_atteint; + return; + } + + if (fseek((*descripteur).descripteur_c, position_finale - 1, + SEEK_SET) != 0) + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return; + } + + if (fread(tampon, (size_t) sizeof(unsigned char), 1, + (*descripteur).descripteur_c) != 1) + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return; + } + + if ((tampon[0] & 0x01) == 0) + { + // Longueur sur sept bits + saut = tampon[0] >> 1; + } + else + { + // Longueurs supérieures + nombre_octets = 2 + ((tampon[0] >> 1) & 0x07); + + if ((position_finale - nombre_octets) < 0) + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_systeme = d_ex_syntaxe; + return; + } + + if (fseek((*descripteur).descripteur_c, position_finale + - nombre_octets, SEEK_SET) != 0) + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + + if (fread(tampon, (size_t) sizeof(unsigned char), + nombre_octets, (*descripteur).descripteur_c) + != (size_t) nombre_octets) + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + + // Récupération du LSB + + saut = (tampon[0] & 0xF0) + | ((tampon[nombre_octets - 1] & 0x0F) >> 4); + + // Autres octets + + for(i = 1; i < (nombre_octets - 1); i++) + { + saut |= ((integer8) tampon[i]) << + (((nombre_octets - 1) - i) * 8); + } + } + + if (position_finale - saut >= 0) + { + if (fseek((*descripteur).descripteur_c, + position_finale - saut, SEEK_SET) != 0) + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_systeme = + d_es_erreur_fichier; + return; + } + } + else + { + liberation(s_etat_processus, s_objet_argument); + + (*s_etat_processus).erreur_execution = + d_ex_debut_de_fichier_atteint; + return; + } } } else @@ -1826,5 +1994,59 @@ instruction_bessel(struct_processus *s_e return; } + + +/* +================================================================================ + Fonction 'backtrace' +================================================================================ + Entrées : +-------------------------------------------------------------------------------- + Sorties : +-------------------------------------------------------------------------------- + Effets de bord : néant +================================================================================ +*/ + +void +instruction_backtrace(struct_processus *s_etat_processus) +{ + (*s_etat_processus).erreur_execution = d_ex; + + if ((*s_etat_processus).affichage_arguments == 'Y') + { + printf("\n BACKTRACE "); + + if ((*s_etat_processus).langue == 'F') + { + printf("(affichage de la pile système)\n\n"); + printf(" Aucun argument\n"); + } + else + { + printf("(print system stack)\n\n"); + printf(" No argument\n"); + } + + return; + } + else if ((*s_etat_processus).test_instruction == 'Y') + { + (*s_etat_processus).nombre_arguments = -1; + return; + } + + if (test_cfsf(s_etat_processus, 31) == d_vrai) + { + if (empilement_pile_last(s_etat_processus, 0) == d_erreur) + { + return; + } + } + + trace(s_etat_processus, stdout); + + return; +} // vim: ts=4