Compilateur et décompilateur de sources malbolge [mlbc]

Description

Salut
Ce programme déchiffre une source Malbolge pour donner un fichier qui contient les instructions que comprend l'interpreteur, il peut aussi generer une source Malbolge à partire de ces instructions. Pour bien comprendre les algorithmes utiliés dans la source, vous avez la source de l'interpreteur original de Malbolge ici: http://www.lscheffer.com/malbolge_interp.html.

Source / Exemple :


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define HELP() printf("Commande invalide\n"); \
			printf("Commandes possibles :\n"); \
			printf("    -dec <options>                                decompiler un fichier\n"); \
			printf("    -c <options>                                  compiler un fichier\n"); \
			printf("    <fichier source>                              imprimer la source en Malbolge du fichier sur l'ecran\n"); \
			printf("    -o <fichier de sortie> <fichier source>       Dirriger le flux de sortie vers un fichier\n"); \
			printf("    -h                                            Afficher ce message d'aide\n");

void compil(char *n_fichier, FILE *src, FILE *sortie);
void decompil(char *n_fichier, FILE *src, FILE *sortie);

int main(int argc, char **argv)
{
	if(argc < 2 || argc > 5)
	{
		HELP()
		return EXIT_FAILURE;
	}
	
	FILE *out = NULL; //La sortie de la soure
	FILE *source = NULL; //Le fichier source
	
	if(!strcmp(argv[1], "-h"))
	{
		HELP()
		return 0;
	}
	
	else if(!strcmp(argv[1], "-c"))
	{
		if(!strcmp(argv[2], "-o"))
		{
			out = fopen(argv[3], "w");
			if(out == NULL)
			{
				fprintf(stderr, "Impossible d'ouvrire le fichier %s en ecriture\n", argv[2]);
				return EXIT_FAILURE;
			}
			
			source = fopen(argv[4], "r");
			if(source == NULL)
			{
				fprintf(stderr, "Impossible d'ouvrire le fichier %s en lecture\n", argv[4]);
				return EXIT_FAILURE;
			}
			
			compil(argv[4], source, out);
		}
		
		else
		{
			out = stdout;
			source = fopen(argv[2], "r");
			if(source == NULL)
			{
				fprintf(stderr, "Impossible d'ouvrire le fichier %s en lecture\n", argv[2]);
				return EXIT_FAILURE;
			}
			
			compil(argv[2], source, out);
		}
	}
	
	else if(!strcmp(argv[1], "-dec"))
	{
		if(!strcmp(argv[2], "-o"))
		{
			out = fopen(argv[3], "w");
			if(out == NULL)
			{
				fprintf(stderr, "Impossible d'ouvrire le fichier %s en ecriture\n", argv[2]);
				return EXIT_FAILURE;
			}
			
			source = fopen(argv[4], "r");
			if(source == NULL)
			{
				fprintf(stderr, "Impossible d'ouvrire le fichier %s en lecture\n", argv[4]);
				return EXIT_FAILURE;
			}
			
			decompil(argv[4], source, out);
		}
		
		else
		{
			out = stdout;
			source = fopen(argv[2], "r");
			if(source == NULL)
			{
				fprintf(stderr, "Impossible d'ouvrire le fichier %s en lecture\n", argv[2]);
				return EXIT_FAILURE;
			}
			
			decompil(argv[2], source, out);
		}
	}

	fclose(source);
	fclose(out);
	
	return 0;
}

void compil(char *n_fichier, FILE *src, FILE *sortie) 
{
	const char instructions[] =
    "+b(29e*j1VMEKLyC})8&m#~W>qxdRp0wkrUo[D7,XTcA\"lI"
    ".v%{gJh4G\\-=O@5`_3i<?Z';FNQuY]szf$!BS/|t:Pn6^Ha"; 
	
	char c;
	int i;
	int j = 0;
	int k = 33;
	unsigned long ligne = 0, caractere = 0;
	
	while((c = fgetc(src)) != EOF)
	{
		if(c == '\n')
		{
			ligne++;
			caractere = 0;
			continue;
		}
		else if(isspace(c)) //si c est un espace
		{
			caractere++;
			continue;
		}
		else
		{
			if(strchr("ji*p</vo", c) == NULL ) //si le caractere actuel est incorrect
			{
				fprintf(stderr, "%s [%ld, %ld]\n\tCaratere invalide", n_fichier, ligne, caractere);
				exit(EXIT_FAILURE);
			}
		
			for(i = 0;i < strlen(instructions); i++) //chercher le caractere dans le tableau des intructions
			{
				if(instructions[i] == c) 
				{
					while(instructions[(k - 33 + j) %94] != c && k != 126) //tant que k est un cacactère ASCII et k n'est pas le bon caractère qu'on cherche
						k++;
						
					fprintf(sortie, "%c", k);
					break;
				}
			}
		}
		
		k = 33;
		j++;
		caractere++;
	}
	fprintf(sortie, "\n");
}

void decompil(char *n_fichier, FILE *src, FILE *sortie)
{
	const char instructions[] =
    "+b(29e*j1VMEKLyC})8&m#~W>qxdRp0wkrUo[D7,XTcA\"lI"
    ".v%{gJh4G\\-=O@5`_3i<?Z';FNQuY]szf$!BS/|t:Pn6^Ha";
	
	int i = 0;
	char c;
	while((c = fgetc(src)) != EOF)
	{
		if(isspace(c) || c == '\n') //si le caractère actuel est un espace ou un saut de ligne on ne fait rien
			continue;
		
		fprintf(sortie, "%c", instructions[(c - 33 + i) % 94]); //regardez la source de Malbolge pour bien comprendre
		i++;
	}
	
	fprintf(sortie, "\n");
}

Conclusion :


J'ai besoin de vos remarques car je ne suis pas sur à 100% du bon fonctionnement de ce programme.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.