#include <stdio.h>
#include <stdlib.h>
#include "stack.h"

static void verifie_parenthese(stack *s, char c, unsigned ligne, unsigned col)
{
  char *p;

  p = stack_pop(s);
  if (!p || *p != c)
    printf("erreur: Symbole incorrect ligne %u, colonne %u.\n", ligne, col);
  free(p);
}

static void verifie_fichier(FILE *f)
{
  stack    *s;
  unsigned  num_ligne, num_col;
  int       c;
  char     *p;

  s = stack_new();
  if (!s)
    exit(-1);

  for (num_ligne = num_col = 1;; num_col++)
    {
      c = fgetc(f);  /* Lecture d'un caractère dans le fichier. */
      switch (c)
        {
        case EOF:    /* Fin du fichier. */
          if (!stack_is_empty(s))
            {
              printf("erreur: %d symbole(s) encore ouvert(s) en fin de fichier.\n",
                     stack_size(s));
              while (stack_size(s))
                free(stack_pop(s));
            }

          stack_free(s);
          return;

        case '\n':
          num_ligne++;
          num_col = 0;
          break;

        case '(':
        case '[':
        case '{':
          p = malloc(1);
          if (!p)
            exit(-1);

          *p = c;

          if (stack_push(s, p))
            exit(-1);
          break;

        case ')':
          verifie_parenthese(s, '(', num_ligne, num_col);
          break;

        case ']':
          verifie_parenthese(s, '[', num_ligne, num_col);
          break;

        case '}':
          verifie_parenthese(s, '{', num_ligne, num_col);
          break;
        }
    }
}

int main(int argc, char *argv[])
{
  FILE *f;

  if (argc != 2)
    {
      printf("usage: %s <nom-fichier>\n", argv[0]);
      exit(-1);
    }

  f = fopen(argv[1], "r");  /* Ouverture d'un fichier en lecture. */
  if (!f)
    {
      printf("impossible d'ouvrir le fichier [%s]\n", argv[1]);
      exit(-1);
    }

  verifie_fichier(f);

  fclose(f);  /* Fermeture du fichier. */
  exit(0);
}
