#inclure "ç.h" entier principale(entier argc, caractère* argv[]) { taille_t i = 0; FICHIER *fichier_d_entree, *fichier_de_la_traduction; caractère *action, *argument; caractère *chemin_d_entree, *chemin_de_la_sortie; entier position_de_l_extension; caractère *extension, *langage, *langage_d_entree; entier succes_de_la_traduction, ecrit; caractère *chemin_de_la_traduction; structure mot_cle_francais *mot_cles; taille_t mot_cles_taille; énumération ccdille_sens sens; caractère *debut_commentaire, *fin_commentaire; entier succes_de_la_compilation; si (argc == 1) { retourner ccdille_utilisation(); } action = argv[1]; si (strcmp(action, "traduire") != 0 && strcmp(action, "construire") != 0) { retourner ccdille_utilisation(); } chemin_de_la_traduction = NUL; chemin_de_la_sortie = NUL; langage = NUL; sens = CCDILLE_A_L_ENDROIT; pour (i = 2; i < (taille_t)argc; ++i) { argument = argv[i]; si (argument[0] == '-' && strlen(argument) > 1) { si (strcmp(argument, "-o") == 0) { i++; chemin_de_la_sortie = argv[i]; } sinon si (strcmp(argument, "-l") == 0) { i++; langage = argv[i]; } sinon si (strcmp(argument, "-1") == 0) { si (strcmp(action, "traduire") != 0) { fprintf(stderr, "Impossible d'utiliser l'option -1 sans l'action traduire\n"); retourner 1; } sens = CCDILLE_A_L_ENVERS; } sinon { fprintf(stderr, "Option non reconnue: %s\n", argument); retourner 1; } continuer; } chemin_d_entree = argument; langage_d_entree = langage; /* J4OUVRE */ si (strcmp(chemin_d_entree, "-") == 0) { fichier_d_entree = stdin; si (langage_d_entree == NUL) { fprintf(stderr, "Langage d'entrée non spécifié, C est utilisé par défaut\n"); langage_d_entree = "c"; } } sinon { si (sens == CCDILLE_A_L_ENDROIT && strcmp(&chemin_d_entree[strlen(chemin_d_entree)-strlen(EXTENSION_DE_FICHIER)], EXTENSION_DE_FICHIER) != 0) { fprintf(stderr, "Type de fichier non supporté %s (un fichier de type %s était attendu)\n", chemin_d_entree, EXTENSION_DE_FICHIER); retourner 1; } /* définir le nom du fichier traduit qui sera produit */ free(chemin_de_la_traduction); chemin_de_la_traduction = malloc((strlen(chemin_d_entree) + strlen(EXTENSION_DE_FICHIER) + 1) * taille de(caractère)); memcpy(chemin_de_la_traduction, chemin_d_entree, strlen(chemin_d_entree) + 1); si (sens == CCDILLE_A_L_ENDROIT) { chemin_de_la_traduction[strlen(chemin_de_la_traduction)-strlen(EXTENSION_DE_FICHIER)] = '\0'; } sinon { strcat(chemin_de_la_traduction, EXTENSION_DE_FICHIER); } /* déterminer l'extension du fichier source */ extension = ""; si (sens == CCDILLE_A_L_ENDROIT) { position_de_l_extension = ccdille_dernier_index_de(chemin_de_la_traduction, '.'); si (position_de_l_extension >= 0) { extension = &chemin_de_la_traduction[position_de_l_extension+1]; } } sinon { position_de_l_extension = ccdille_dernier_index_de(chemin_d_entree, '.'); si (position_de_l_extension >= 0) { extension = &chemin_d_entree[position_de_l_extension+1]; } } /* auto-détection du langage d'entrée en fonction de l'extension du fichier */ si (langage_d_entree == NUL) { si (strcmp(extension, "c") == 0 || strcmp(extension, "h") == 0) { langage_d_entree = "c"; } sinon si (strcmp(extension, "ml") == 0 || strcmp(extension, "mli") == 0) { langage_d_entree = "ml"; } sinon si (strcmp(extension, "rs") == 0) { langage_d_entree = "rs"; } sinon { fprintf(stderr, "Extension %s non supportée\n", extension); retourner 1; } } fichier_d_entree = fopen(chemin_d_entree, "r"); si (fichier_d_entree == NUL) { fprintf(stderr, "Le fichier %s n'a pas pu être ouvert\n", chemin_d_entree); retourner 1; } } /* seuls C et OCaml sont supportés pour le moment */ si (strcmp(langage_d_entree, "c") == 0) { mot_cles = mot_cles_c; mot_cles_taille = taille de(mot_cles_c)/taille de(*mot_cles_c); debut_commentaire = (caractère*) DEBUT_COMMENTAIRE_C; fin_commentaire = (caractère*) FIN_COMMENTAIRE_C; } sinon si (strcmp(langage_d_entree, "ml") == 0) { mot_cles = mot_cles_ml; mot_cles_taille = taille de(mot_cles_ml)/taille de(*mot_cles_ml); debut_commentaire = (caractère*) DEBUT_COMMENTAIRE_ML; fin_commentaire = (caractère*) FIN_COMMENTAIRE_ML; } sinon si (strcmp(langage_d_entree, "rs") == 0) { mot_cles = mot_cles_rs; mot_cles_taille = taille de(mot_cles_rs)/taille de(*mot_cles_rs); debut_commentaire = (caractère*) DEBUT_COMMENTAIRE_RS; fin_commentaire = (caractère*) FIN_COMMENTAIRE_RS; } sinon { fprintf(stderr, "Langage %s non supporté\n", langage_d_entree); retourner 1; } /* si on traduit sans compiler, écrire la traduction dans le fichier de sortie, si spécifié */ si (strcmp(action, "traduire") == 0 && chemin_de_la_sortie != NUL) { free(chemin_de_la_traduction); chemin_de_la_traduction = malloc((strlen(chemin_de_la_sortie) + 1) * taille de(caractère)); memcpy(chemin_de_la_traduction, chemin_de_la_sortie, strlen(chemin_de_la_sortie) + 1); } /* ouvrir le fichier où la traduction sera écrite */ si (chemin_de_la_traduction == NUL || strcmp(chemin_de_la_traduction, "-") == 0) { fichier_de_la_traduction = stdout; } sinon { fichier_de_la_traduction = fopen(chemin_de_la_traduction, "w"); si (fichier_de_la_traduction == NUL) { fprintf(stderr, "Failed to create a new fichier.\n"); retourner 8; } } /* écrire l'en-tête de traduction si nécessaire */ si (sens == CCDILLE_A_L_ENDROIT) { ecrit = fprintf(fichier_de_la_traduction, "%s%s%s\n\n", debut_commentaire, EN_TETE_DE_TRADUCTION, fin_commentaire); si (ecrit < 0) { retourner 9; } } /* read words from the fichier */ succes_de_la_traduction = ccdille_traduire_fichier(fichier_d_entree, fichier_de_la_traduction, mot_cles, mot_cles_taille, sens); si (succes_de_la_traduction != 0) { retourner succes_de_la_traduction; } /* JE FERME */ fclose(fichier_d_entree); fclose(fichier_de_la_traduction); } succes_de_la_compilation = 0; si (strcmp(action, "construire") == 0) { si (chemin_de_la_sortie == NUL) { chemin_de_la_sortie = "a.sortie"; } si (strcmp(langage_d_entree, "c") == 0) { succes_de_la_compilation = execl("/usr/bin/cc", "cc", "-o", chemin_de_la_sortie, chemin_de_la_traduction, NUL); } sinon si (strcmp(langage_d_entree, "ml") == 0) { succes_de_la_compilation = execl("/usr/bin/ocamlc", "ocamlc", "-o", chemin_de_la_sortie, chemin_de_la_traduction, NUL); } sinon { fprintf(stderr, "Langage %s non supporté à la compilation\n", langage_d_entree); succes_de_la_compilation = 1; } } free(chemin_de_la_traduction); retourner succes_de_la_compilation; } entier ccdille_utilisation() { fprintf(stderr, "Utilisation : ç traduire|construire [-1] [-l langage] [-o a.sortie] [entrée...]\n"); retourner 1; } entier ccdille_traduire_fichier(FICHIER* entree, FICHIER* sortie, structure mot_cle_francais *mot_cles, taille_t mot_cles_taille, énumération ccdille_sens sens) { caractère tampon[TAILLE_DU_TAMPON]; entier c; entier succes_de_la_traduction; taille_t longueur; taille_t ecrit; longueur = 0; pour (;;) { c = fgetc(entree); si (c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '(' || c == ')' || c == '/' || c == '*' || c == ';' || c == '|' || c == '&' || c == '*' || c == '!' || c == '=' || c == ':' || c == EOF) { succes_de_la_traduction = ccdille_traduire_mot(mot_cles, mot_cles_taille, (caractère*)tampon, &longueur, sens); si (succes_de_la_traduction || c == EOF) { ecrit = fwrite((vide*)tampon, taille de(caractère), longueur, sortie); si (ecrit < longueur) { retourner 6; } si (c == EOF) { casser; } tampon[0] = (caractère) c; ecrit = fwrite((void*)tampon, taille de(caractère), 1, sortie); si (ecrit < 1) { retourner 7; } longueur = 0; continuer; } } tampon[longueur] = (caractère) c; ++longueur; } retourner 0; } entier ccdille_traduire_mot(structure mot_cle_francais *mot_cles, taille_t mot_cles_taille, caractère* mot_a_traduire, taille_t* longueur, énumération ccdille_sens sens) { taille_t i; énumération ccdille_comparaison_de_chaine_de_caractere_resultat resultat; structure mot_cle_francais mot_cle; caractère *mot, *traduction; pour (i = 0; i < mot_cles_taille; i++) { mot_cle = mot_cles[i]; si (sens == CCDILLE_A_L_ENDROIT) { mot = mot_cle.mot; traduction = mot_cle.traduction; } sinon { mot = mot_cle.traduction; traduction = mot_cle.mot; } resultat = ccdille_comparaison_de_chaine_de_caractere(mot_a_traduire, *longueur, mot, strlen(mot)); commuter (resultat) { cas CCDILLE_CORRESPONDANCE: *longueur = strlen(traduction); memcpy(mot_a_traduire, traduction, *longueur); retourner 1; cas CCDILLE_PREFIXE: retourner 0; cas CCDILLE_PAS_DE_CORRESPONDANCE: casser; /* mdr ya pas de par défaut */ } } retourner 1; } taille_t ccdille_min(taille_t a, taille_t b) { retourner a <= b ? a : b; } entier ccdille_dernier_index_de(caractère* mot, caractère c) { entier i = strlen(mot) - 1; tant que (i >= 0) { si (mot[i] == c) { retourner i; } i--; } retourner -1; } énumération ccdille_comparaison_de_chaine_de_caractere_resultat ccdille_comparaison_de_chaine_de_caractere(caractère constant* a, taille_t taille_de_a, caractère constant* b, taille_t taille_de_b) { taille_t i; pour (i = 0; i < ccdille_min(taille_de_a, taille_de_b); i++) { si (a[i] != b[i]) { retourner CCDILLE_PAS_DE_CORRESPONDANCE; } } si (taille_de_a == taille_de_b) { retourner CCDILLE_CORRESPONDANCE; } si (taille_de_a > taille_de_b || b[i] != ' ') { retourner CCDILLE_PAS_DE_CORRESPONDANCE; } retourner CCDILLE_PREFIXE; }