Indenteur de code

Description

Objectif : transformer du texte ayant une typologie particulière (celle d'un langage de programmation à la norme C) mal écrit (sur une seule ligne par exemple) en du texte plus facilement lisible de n'importe quel utilisateur.

Programmé en C.
L'appel dans un autre programme peut se faire à l'aide la fonction void Indent(FILE* pFile, int nbtabs, char fstr[], long int i, char c);
Attention cependant à supprimer le point d'entrée avant d'en envisager toute exploitation.

Source / Exemple :


#include <stdio.h>
#define MAX_FILE 1000000
typedef enum 
{
  false, true, halftrue
}
 boolean;

void BeginLine(int nbtabs, char fstr[], long int index)
{
  int j;
  for(j=0;j<2*nbtabs;j++)fstr[index++] = ' ';
   
}
void Indent(FILE* pFile, int nbtabs, char fstr[], long int i, char c)
{
  boolean newline=true, expr=false, cond=false, comm=false;  
  while(i<MAX_FILE && !feof(pFile))
  {
    c = fgetc(pFile);
    switch(c)
    {
      case ' ':
      if(newline==true)break;
      else fstr[i++] = c;break;
      case ',':fstr[i++] = c;
      if(!expr)fstr[i++] = ' ';
      break;
      case '*':
          if(fstr[i-1]=='/')
          comm=true;
          fstr[i++] = c;
          break;
      case '/':
          if(fstr[i-1]=='*')comm=false;
          if(fstr[i-1]=='/')comm=halftrue;
          fstr[i++] = c;
          break;
      case '=':
      if(fstr[i-1]!='&' && fstr[i-1]!='.' && fstr[i-1]!='+' && fstr[i-1]!='*' &&
         fstr[i-1]!='/' && fstr[i-1]!='|' && fstr[i-1]!='!' && fstr[i-1]!='=' &&
         fstr[i-1]!='<' && fstr[i-1]!='>'&& fstr[i-1]!='~'  && !expr && !cond && 
         comm!=true)
      fstr[i++] = ' ';     
      newline = false;
      fstr[i++] = c;
      if(!expr && !cond && comm!=true)fstr[i++] = ' ';
      break;
      case '\'':newline = false;
      if(fstr[i-1]!='\\')
      {
          switch(expr)
          {    
          case false:expr = halftrue;break;
          case halftrue:expr = false;break;
          default:break;
          }    
      }    
      fstr[i++] = c;
      break;
      case '"':
      newline = false;
      if(fstr[i-1]!='\\')
      {
          switch(expr)
          {    
          case false:expr = true;break;
          case true:expr = false;break;
          default:break;
          }    
      }    
      if(fstr[i-1]!='\\')expr = !expr;
      fstr[i++] = c;
      break;
      case '(':newline = false;cond=true;fstr[i++]=c;break;
      case ')':cond = false;
      fstr[i++] = c;
      break;
      case '{':case '}':if(!expr && !cond && comm!=true)
      {
        if(newline==false);  
        fstr[i++] = '\n';
        if(c=='}')nbtabs--;
        BeginLine(nbtabs, fstr, i);
        i+= 2*nbtabs;
        fstr[i++] = c;
        fstr[i++] = '\n';
        newline=true;
        if(c=='{')nbtabs++;
        BeginLine(nbtabs, fstr, i);
        i+= 2*nbtabs;
      }
      else fstr[i++] = c;
      break;
      case '\n':
      if(newline==true)break;
      if(!expr && !cond && comm!=true)
      {
        comm=false;  
        fstr[i++] = c;
        BeginLine(nbtabs, fstr, i);
        i+= 2*nbtabs;
        newline=true;
      }
      else fstr[i++] = c;
      break;
      case ';':if(!expr && !cond && comm!=true && (i>3 && 
                  (fstr[i-1]!='p' || fstr[i-2]!='m' || fstr[i-3]!='a')) && 
                  (i>4 && (fstr[i-1]!='p' || fstr[i-2]!='s' || fstr[i-3]!='b' ||
                  fstr[i-4]!='n')))
      {
        fstr[i++] = c;
        fstr[i++] = '\n';
        BeginLine(nbtabs, fstr, i);
        i+= 2*nbtabs;
        newline=true;
      }
      else fstr[i++] = c;
      break;
      default:newline = false;fstr[i++] = c;
      break;
    }
  }
  fstr[i-1] = '\0';
  
}
int main(int argc, char *argv[])
{
  FILE* pFile;
  char c, fstr[MAX_FILE] = "\0";
  long int i = 1;
  int nbtabs = 0;
  pFile = fopen(argv[1], "r");
  i=0;
  if(pFile==NULL)
  {
    perror("Indenteur:Erreur lors de l'ouverture du fichier.\nCode d'erreur");
    return 1;
    
  }
  Indent(pFile, nbtabs, fstr, i, c);
  fclose(pFile);
  if(argv[2]!=NULL)pFile = fopen(argv[2], "w+");
  else pFile = fopen("a.txt", "w+");
  if(pFile==NULL)
  {
    perror("Indenteur:Erreur lors de la création du fichier.\nCode d'erreur");
    return 1;
  }
  fputs(fstr, pFile);
  fclose(pFile);
  printf("Indenteur:Pas d'erreur a l'execution\nCode de sortie : 0\n");
  return 0;
}

Conclusion :


Le programme compilé doit être executé après avoir mis en arguments :
- en premier lieu le fichier source (celui contenant le texte non indenté)
- ensuite le fichier destination (peut ne pas exister)

Voici la syntaxe: indent [src] [dst]

Anecdote : pour parfaire le programme j'ai dû employer l'usage d'un type enuméré tout à fait particulier : le booléen à trois valeurs : faux, vrai et à moitié vrai.

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.