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

char* strdup(const char *str)
{
  int len = strlen(str);
  char *str2 = malloc((len + 1) * sizeof (char));
  if (str2) strcpy(str2, str);
  return str2;
}

int main()
{
  FILE *f = stdin;
  /** @todo evaluation of command line arguments could override f with fopen(). */
  /* read input */
  if (!f) {
    fprintf(stderr, "ERROR: Cannot read input!\n");
    return 1;
  }
  int nGates = 0, nVars = 0;
  char **vars = NULL;
  char buffer[80];
  for (int iLine = 1; fgets(buffer, sizeof buffer, f); ++iLine) {
    char *op = strtok(buffer, " \t\r\n");
    if (!op
      || strcmp(op, "AND") != 0 && strcmp(op, "OR") != 0 && strcmp(op, "XOR") != 0
      && strcmp(op, "NAND") != 0 && strcmp(op, "NOR") != 0) {
      fprintf(stderr, "ERROR in line %d: OP expected!\n", iLine);
      continue;
    }
    char *var;
    while (var = strtok(NULL, " \t\r\n")) {
      if (var[0] == 't') {
        int found = 0;
        for (int i = 0; i < nVars; ++i) {
          if (found = (strcmp(var, vars[i]) == 0)) break;
        }
        if (found) continue; /* continues the while (var = strtok(NULL, " \t\r\n")) loop */
        ++nVars;
        vars = realloc(vars, sizeof (char*) * nVars);
        if (!vars) {
          fprintf(stderr, "ERROR: Out of memory!\n");
          return 1;
        }
        int iVar = nVars - 1;
        vars[iVar] = strdup(var);
        printf("Var. #%d: '%s'\n", iVar, var);
      }
    }
    ++nGates;
  }
  /* evaluate input */
  printf("Report:\n");
  printf("nGates: %d, nVars: %d\n", nGates, nVars);
  for (int i = 0; i < nVars; ++i) {
    printf("vars[%d]: '%s'\n", i, vars[i]);
  }
  /* clean-up */
  for (int i = 0; i < nVars; ++i) free(vars[i]);
  free(vars);
  /* done */
  return 0;
}