/* ================================================================================ RPL/2 (R) version 4.1.4 Copyright (C) 1989-2011 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" /* ================================================================================ Routine de formation des données pour l'envoi de flux binaires ================================================================================ Entrées : structure sur l'état du processus et objet à afficher -------------------------------------------------------------------------------- Sorties : chaine de caractères -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ unsigned char * formateur_flux(struct_processus *s_etat_processus, unsigned char *donnees, long *longueur) { unsigned char *chaine; unsigned char *ptr_ecriture; unsigned char *ptr_lecture; if ((chaine = malloc((strlen(donnees) + 1) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } ptr_lecture = donnees; ptr_ecriture = chaine; while((*ptr_lecture) != d_code_fin_chaine) { (*ptr_ecriture) = (*ptr_lecture); // Début de la séquence d'échappement if ((*ptr_lecture) == '\\') { if ((*(ptr_lecture + 1)) == '"') { ptr_lecture++; (*ptr_ecriture) = '\"'; } else if ((*(ptr_lecture + 1)) == 'b') { ptr_lecture++; (*ptr_ecriture) = '\b'; } else if ((*(ptr_lecture + 1)) == 'n') { ptr_lecture++; (*ptr_ecriture) = '\n'; } else if ((*(ptr_lecture + 1)) == 't') { ptr_lecture++; (*ptr_ecriture) = '\t'; } else if ((*(ptr_lecture + 1)) == 'x') { ptr_lecture += 2; if ((*ptr_lecture) != d_code_fin_chaine) { if ((*(ptr_lecture + 1)) != d_code_fin_chaine) { logical1 erreur; unsigned char ec; erreur = d_faux; switch(*ptr_lecture) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ec = (*ptr_lecture) - '0'; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': ec = ((*ptr_lecture) - 'A') + 10; break; default: ec = 0; erreur = d_vrai; break; } ec *= 0x10; ptr_lecture++; switch(*ptr_lecture) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ec += (*ptr_lecture) - '0'; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': ec += ((*ptr_lecture) - 'A') + 10; break; default: erreur = d_vrai; break; } (*ptr_ecriture) = ec; if (erreur == d_vrai) { if ((*s_etat_processus).langue == 'F') { printf("+++Information : " "Séquence d'échappement " "inconnue [%d]\n", (int) getpid()); } else { printf("+++Warning : Unknown " "escape code " "[%d]\n", (int) getpid()); } } } else { if ((*s_etat_processus).langue == 'F') { printf("+++Information : " "Séquence d'échappement " "inconnue [%d]\n", (int) getpid()); } else { printf("+++Warning : Unknown escape code " "[%d]\n", (int) getpid()); } } } else { if ((*s_etat_processus).langue == 'F') { printf("+++Information : " "Séquence d'échappement " "inconnue [%d]\n", (int) getpid()); } else { printf("+++Warning : Unknown escape code " "[%d]\n", (int) getpid()); } } } else if ((*(ptr_lecture + 1)) == '\\') { ptr_lecture++; } else { if ((*s_etat_processus).langue == 'F') { printf("+++Information : Séquence d'échappement " "inconnue [%d]\n", (int) getpid()); } else { printf("+++Warning : Unknown escape code " "[%d]\n", (int) getpid()); } } } ptr_ecriture++; ptr_lecture++; } (*ptr_ecriture) = d_code_fin_chaine; if ((chaine = realloc(chaine, ((((*longueur) = ptr_ecriture - chaine)) + 1) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } return(chaine); } /* ================================================================================ Routine testant la validité d'une chaîne de caractères ================================================================================ Entrées : structure sur l'état du processus et chaîne courante -------------------------------------------------------------------------------- Sorties : pointeur sur le caractère suivant -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ logical1 validation_chaine(unsigned char *chaine) { if (chaine == NULL) { return(d_faux); } while((*chaine) != d_code_fin_chaine) { if ((*chaine) == '\\') { if ((*(chaine + 1)) == '"') { chaine += 2; } else if ((*(chaine + 1)) == 'b') { chaine += 2; } else if ((*(chaine + 1)) == 'n') { chaine += 2; } else if ((*(chaine + 1)) == 't') { chaine += 2; } else if ((*(chaine + 1)) == 'x') { if ((*(chaine + 2)) != d_code_fin_chaine) { if ((*(chaine + 3)) != d_code_fin_chaine) { switch(*(chaine + 2)) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': break; default: return(d_faux); break; } switch(*(chaine + 3)) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': break; default: return(d_faux); break; } } else { return(d_faux); } } else { return(d_faux); } chaine += 4; } else if ((*(chaine + 1)) == '\\') { chaine += 2; } else { // Tous les autres cas sont invalides return(d_faux); } } else { chaine++; } } return(d_vrai); } /* ================================================================================ Routine permettant de trouver le caractère suivant dans une chaîne ================================================================================ Entrées : structure sur l'état du processus et chaîne courante -------------------------------------------------------------------------------- Sorties : pointeur sur le caractère suivant -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ static inline unsigned char * prochain_caractere(struct_processus *s_etat_processus, unsigned char *chaine) { unsigned char *suivant; if (chaine == NULL) { return(NULL); } if ((*chaine) == '\\') { if ((*(chaine + 1)) == '"') { suivant = chaine + 2; } else if ((*(chaine + 1)) == 'b') { suivant = chaine + 2; } else if ((*(chaine + 1)) == 'n') { suivant = chaine + 2; } else if ((*(chaine + 1)) == 't') { suivant = chaine + 2; } else if ((*(chaine + 1)) == 'x') { if ((*(chaine + 2)) != d_code_fin_chaine) { if ((*(chaine + 3)) != d_code_fin_chaine) { logical1 erreur; erreur = d_faux; switch(*(chaine + 2)) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': break; default: erreur = d_vrai; break; } switch(*(chaine + 3)) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': break; default: erreur = d_vrai; break; } if (erreur == d_vrai) { if ((*s_etat_processus).langue == 'F') { printf("+++Information : " "Séquence d'échappement " "inconnue [%d]\n", (int) getpid()); } else { printf("+++Warning : Unknown " "escape code " "[%d]\n", (int) getpid()); } return(NULL); } suivant = chaine + 4; } else { if ((*s_etat_processus).langue == 'F') { printf("+++Information : " "Séquence d'échappement " "inconnue [%d]\n", (int) getpid()); } else { printf("+++Warning : Unknown escape code " "[%d]\n", (int) getpid()); } return(NULL); } } else { if ((*s_etat_processus).langue == 'F') { printf("+++Information : " "Séquence d'échappement " "inconnue [%d]\n", (int) getpid()); } else { printf("+++Warning : Unknown escape code " "[%d]\n", (int) getpid()); } return(NULL); } } else if ((*(chaine + 1)) == '\\') { suivant = chaine + 2; } else { if ((*s_etat_processus).langue == 'F') { printf("+++Information : Séquence d'échappement " "inconnue [%d]\n", (int) getpid()); } else { printf("+++Warning : Unknown escape code " "[%d]\n", (int) getpid()); } return(NULL); } } else { suivant = chaine + 1; } return(suivant); } /* ================================================================================ Routine donnant la longueur d'une chaîne de caractères ================================================================================ Entrées : structure sur l'état du processus et chaîne -------------------------------------------------------------------------------- Sorties : longueur de la chaîne -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ integer8 longueur_chaine(struct_processus *s_etat_processus, unsigned char *chaine) { integer8 nombre_caracteres; unsigned char *pointeur; pointeur = chaine; nombre_caracteres = 0; if ((*pointeur) == '\0') { return(0); } do { if ((pointeur = prochain_caractere(s_etat_processus, pointeur)) == NULL) { return(0); } nombre_caracteres++; } while((*pointeur) != 0); return(nombre_caracteres); } /* ================================================================================ Routine retournant un pointeur sur le i-ème caractère d'une chaîne ================================================================================ Entrées : structure sur l'état du processus et chaîne -------------------------------------------------------------------------------- Sorties : longueur de la chaîne -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ unsigned char * pointeur_ieme_caractere(struct_processus *s_etat_processus, unsigned char *chaine, integer8 position) { integer8 i; unsigned char *pointeur; if ((pointeur = chaine) == NULL) { return(NULL); } for(i = 0; i < position; i++) { pointeur = prochain_caractere(s_etat_processus, pointeur); if ((*pointeur) == d_code_fin_chaine) { return(pointeur); } } return(pointeur); } // vim: ts=4