/* ================================================================================ RPL/2 (R) version 4.1.32 Copyright (C) 1989-2020 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 chaînage du programme (lecture du fichier puis constitution de la chaîne exécutable) ================================================================================ Entrées: structure processus -------------------------------------------------------------------------------- Sortie: drapeau d'erreur -------------------------------------------------------------------------------- Effets de bord: néant ================================================================================ */ logical1 chainage(struct_processus *s_etat_processus) { char *nom_fichier_temporaire; file *f_source; int caractere; int erreur; logical1 drapeau_fin; logical1 erreur_os; logical1 existence; logical1 initialisation; logical1 ouverture; logical1 presence_chaine; integer8 i; integer8 nombre_caracteres_source; unsigned char *commande; unsigned char *executable_candidat; # ifndef OS2 unsigned char *instructions = "%s/bin/%s %s | " "%s/bin/rpliconv `%s/bin/rplfile " "-m %s/share/rplfiles -i %s | " "%s/bin/rplawk " "'{ print $3; }' | %s/bin/rplawk -F= " "'{ if ($2 != \"\") printf(\"-f %%s\", " "$2); }'` -t %s//IGNORE > %s"; # else unsigned char *instructions = BOURNE_SHELL " -c \"" "%s/bin/%s %s | " "%s/bin/rpliconv `%s/bin/rplfile " "-m %s/share/rplfiles -i %s | " "%s/bin/rplawk " "'{ print $3; }' | %s/bin/rplawk -F= " "'{ if ($2 != \\\"\\\") " "printf(\\\"-f %%s\\\", " "$2); }'` -t %s//IGNORE > %s\""; # endif unsigned long unite_fichier; if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_analyse) != 0) { printf("\n"); if ((*s_etat_processus).langue == 'F') { printf("[%d] Appel au préprocesseur\n", (int) getpid()); } else { printf("[%d] Preprocessing\n", (int) getpid()); } fflush(stdout); } erreur = caracteristiques_fichier(s_etat_processus, (*s_etat_processus).nom_fichier_source, &existence, &ouverture, &unite_fichier); erreur_os = d_absence_erreur; if ((existence == d_vrai) && (erreur == 0)) { if ((nom_fichier_temporaire = creation_nom_fichier( s_etat_processus, (*s_etat_processus) .chemin_fichiers_temporaires)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; return(d_erreur); } // Avant d'exécuter la commande, on teste les sommes de hashage // des utilitaires de la famille RPL/2. if ((*s_etat_processus).rpl_home == NULL) { if ((commande = (unsigned char *) malloc((strlen(ds_preprocesseur) + (2 * strlen((*s_etat_processus).nom_fichier_source)) + (6 * strlen(d_exec_path)) + strlen(d_locale) + strlen(nom_fichier_temporaire) + strlen(instructions) - 21) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(nom_fichier_temporaire); return(d_erreur); } sprintf(commande, instructions, d_exec_path, ds_preprocesseur, (*s_etat_processus).nom_fichier_source, d_exec_path, d_exec_path, d_exec_path, (*s_etat_processus).nom_fichier_source, d_exec_path, d_exec_path, d_locale, nom_fichier_temporaire); if (alsprintf(s_etat_processus, &executable_candidat, "%s/bin/rpliconv", d_exec_path) < 0) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } if (controle_integrite(s_etat_processus, executable_candidat, "rpliconv") != d_vrai) { (*s_etat_processus).erreur_systeme = d_es_somme_controle; return(d_erreur); } free(executable_candidat); if (alsprintf(s_etat_processus, &executable_candidat, "%s/bin/rplfile", d_exec_path) < 0) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } if (controle_integrite(s_etat_processus, executable_candidat, "rplfile") != d_vrai) { (*s_etat_processus).erreur_systeme = d_es_somme_controle; return(d_erreur); } free(executable_candidat); if (alsprintf(s_etat_processus, &executable_candidat, "%s/bin/rplpp", d_exec_path) < 0) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } if (controle_integrite(s_etat_processus, executable_candidat, "rplpp") != d_vrai) { (*s_etat_processus).erreur_systeme = d_es_somme_controle; return(d_erreur); } free(executable_candidat); if (alsprintf(s_etat_processus, &executable_candidat, "%s/bin/rplawk", d_exec_path) < 0) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } if (controle_integrite(s_etat_processus, executable_candidat, "rplawk") != d_vrai) { (*s_etat_processus).erreur_systeme = d_es_somme_controle; return(d_erreur); } free(executable_candidat); } else { if ((commande = (unsigned char *) malloc((strlen(ds_preprocesseur) + (2 * strlen((*s_etat_processus).nom_fichier_source)) + (6 * strlen((*s_etat_processus).rpl_home)) + strlen(d_locale) + strlen(nom_fichier_temporaire) + strlen(instructions) - 21) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; free(nom_fichier_temporaire); return(d_erreur); } sprintf(commande, instructions, (*s_etat_processus).rpl_home, ds_preprocesseur, (*s_etat_processus).nom_fichier_source, (*s_etat_processus).rpl_home, (*s_etat_processus).rpl_home, (*s_etat_processus).rpl_home, (*s_etat_processus).nom_fichier_source, (*s_etat_processus).rpl_home, (*s_etat_processus).rpl_home, d_locale, nom_fichier_temporaire); if (alsprintf(s_etat_processus, &executable_candidat, "%s/bin/rpliconv", (*s_etat_processus).rpl_home) < 0) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } if (controle_integrite(s_etat_processus, executable_candidat, "rpliconv") != d_vrai) { (*s_etat_processus).erreur_systeme = d_es_somme_controle; return(d_erreur); } free(executable_candidat); if (alsprintf(s_etat_processus, &executable_candidat, "%s/bin/rplfile", (*s_etat_processus).rpl_home) < 0) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } if (controle_integrite(s_etat_processus, executable_candidat, "rplfile") != d_vrai) { (*s_etat_processus).erreur_systeme = d_es_somme_controle; return(d_erreur); } free(executable_candidat); if (alsprintf(s_etat_processus, &executable_candidat, "%s/bin/rplpp", (*s_etat_processus).rpl_home) < 0) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } if (controle_integrite(s_etat_processus, executable_candidat, "rplpp") != d_vrai) { (*s_etat_processus).erreur_systeme = d_es_somme_controle; return(d_erreur); } free(executable_candidat); if (alsprintf(s_etat_processus, &executable_candidat, "%s/bin/rplawk", (*s_etat_processus).rpl_home) < 0) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } if (controle_integrite(s_etat_processus, executable_candidat, "rplawk") != d_vrai) { (*s_etat_processus).erreur_systeme = d_es_somme_controle; return(d_erreur); } free(executable_candidat); } if ((f_source = popen(commande, "r")) == NULL) { (*s_etat_processus).erreur_systeme = d_es_processus; free(nom_fichier_temporaire); return(d_erreur); } if (pclose(f_source) != EXIT_SUCCESS) { (*s_etat_processus).erreur_systeme = d_es_processus; free(nom_fichier_temporaire); return(d_erreur); } free(commande); if ((f_source = fopen(nom_fichier_temporaire, "r")) == NULL) { (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; if (destruction_fichier(nom_fichier_temporaire) == d_erreur) { free(nom_fichier_temporaire); return(d_erreur); } free(nom_fichier_temporaire); return(d_erreur); } nombre_caracteres_source = 0; while(getc(f_source) != EOF) { nombre_caracteres_source++; } (*s_etat_processus).definitions_chainees = (unsigned char *) malloc((((size_t) nombre_caracteres_source) + 1) * sizeof(unsigned char)); if ((*s_etat_processus).definitions_chainees == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; if (destruction_fichier(nom_fichier_temporaire) == d_erreur) { free(nom_fichier_temporaire); return(d_erreur); } return(d_erreur); } else { rewind(f_source); presence_chaine = d_faux; i = 0; drapeau_fin = d_faux; initialisation = d_vrai; /* * Élimination du sharp-bang si nécessaire et des caractères * inutiles. Conversion de caractères. */ while(drapeau_fin == d_faux) { if ((caractere = getc(f_source)) != EOF) { if (initialisation == d_vrai) { if (caractere == '#') { if ((caractere = getc(f_source)) != EOF) { if (caractere == '!') { do { caractere = getc(f_source); } while((caractere != EOF) && (caractere != d_code_retour_chariot)); } else { rewind(f_source); caractere = getc(f_source); } } } initialisation = d_faux; } if ((caractere == d_code_retour_chariot) || (caractere == d_code_tabulation) || ((caractere == d_code_espace) && (presence_chaine == d_faux))) { do { caractere = getc(f_source); } while(((caractere == d_code_retour_chariot) || (caractere == d_code_tabulation) || ((caractere == d_code_espace) && (presence_chaine == d_faux))) && (caractere != EOF)); if (caractere != EOF) { ((*s_etat_processus).definitions_chainees)[i++] = d_code_espace; } else { drapeau_fin = d_vrai; } } if (((int) (((*s_etat_processus).definitions_chainees)[i] = ((unsigned char) caractere))) == '\"') { if (i > 0) { if (((*s_etat_processus).definitions_chainees) [i - 1] != '\\') { presence_chaine = (presence_chaine == d_faux) ? d_vrai : d_faux; } } i++; } else { i++; } } else { drapeau_fin = d_vrai; } } if ((caractere == EOF) && (i > 0)) { i--; } ((*s_etat_processus).definitions_chainees)[i] = d_code_fin_chaine; erreur_os = d_absence_erreur; } (*s_etat_processus).longueur_definitions_chainees = (integer8) strlen((*s_etat_processus).definitions_chainees); if (fclose(f_source) != 0) { (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; if (destruction_fichier(nom_fichier_temporaire) == d_erreur) { free(nom_fichier_temporaire); return(d_erreur); } free(nom_fichier_temporaire); return(d_erreur); } if (destruction_fichier(nom_fichier_temporaire) == d_erreur) { (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; free(nom_fichier_temporaire); return(d_erreur); } free(nom_fichier_temporaire); } else { (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; erreur_os = d_erreur; } if (((*s_etat_processus).definitions_chainees = realloc((*s_etat_processus).definitions_chainees, (((size_t) (*s_etat_processus).longueur_definitions_chainees) + 1) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } return(erreur_os); } /* ================================================================================ Routine de compactage d'une chaîne de caractères Tous les espaces et les retours à ligne surnuméraires sont enlevés. ================================================================================ Entrées: structure processus -------------------------------------------------------------------------------- Sortie: drapeau d'erreur -------------------------------------------------------------------------------- Effets de bord: néant ================================================================================ */ unsigned char * compactage(struct_processus *s_etat_processus, unsigned char *chaine) { logical1 drapeau_fin; logical1 presence_chaine; unsigned char caractere; unsigned char *ptr_ecriture; unsigned char *ptr_lecture; if (chaine == NULL) { return(NULL); } presence_chaine = d_faux; drapeau_fin = d_faux; ptr_lecture = chaine; ptr_ecriture = chaine; while(drapeau_fin == d_faux) { if ((caractere = (*ptr_lecture++)) != d_code_fin_chaine) { if ((caractere == d_code_retour_chariot) || (caractere == d_code_tabulation) || ((caractere == d_code_espace) && (presence_chaine == d_faux))) { do { caractere = (*ptr_lecture++); } while(((caractere == d_code_retour_chariot) || (caractere == d_code_tabulation) || ((caractere == d_code_espace) && (presence_chaine == d_faux))) && (caractere != d_code_fin_chaine)); if (caractere != d_code_fin_chaine) { (*ptr_ecriture++) = d_code_espace; } else { drapeau_fin = d_vrai; } } if (((*ptr_ecriture++) = caractere) == '\"') { presence_chaine = (presence_chaine == d_faux) ? d_vrai : d_faux; } } else { drapeau_fin = d_vrai; } } (*ptr_ecriture) = d_code_fin_chaine; return(realloc(chaine, (strlen(chaine) + 1) * sizeof(unsigned char))); } // vim: ts=4