Codebase list filtergen / HEAD t / emit.c
HEAD

Tree @HEAD (Download .tar.gz)

emit.c @HEADraw · history · blame

/* ast emitter
 * output should be identical (syntactically) to the input
 */

#include <stdio.h>
#include <stdlib.h>
#include "../ast.h"
#include "../parser.h"

int yyparse(void *);
int emittrace = 0;

#define EMIT(x) void emit_##x(struct x##_s *n)

#define eprint(x)                                                              \
  if (emittrace)                                                               \
  fprintf(stderr, x)

EMIT(specifier_list);

EMIT(subrule_list) {
  if (n->subrule_list) {
    eprint("emitting subrule_list\n");
    emit_subrule_list(n->subrule_list);
    printf(";\n");
  }
  if (n->specifier_list) {
    eprint("emitting specifier_list\n");
    emit_specifier_list(n->specifier_list);
  }
}

EMIT(chaingroup_specifier) {
  printf("[");
  if (n->name) {
    printf(" \"%s\"", n->name);
  }
  printf("\n");
  eprint("emitting subrule_list\n");
  emit_subrule_list(n->list);
  printf("]");
}

EMIT(compound_specifier) {
  printf("{");
  if (n->list) {
    eprint("emitting subrule_list\n");
    emit_subrule_list(n->list);
  }
  printf("}");
}

EMIT(option_specifier) {
  switch (n->type) {
  case TOK_LOCAL:
    printf("local");
    break;
  case TOK_FORWARD:
    printf("forward");
    break;
  case TOK_ONEWAY:
    printf("oneway");
    break;
  case TOK_LOG:
    if (n->logmsg) {
      printf("log text \"%s\"", n->logmsg);
    } else {
      printf("log");
    }
    break;
  default:
    printf("error");
    break;
  }
}

EMIT(icmptype_argument) { printf("%s", n->icmptype); }

EMIT(icmptype_argument_list) {
  if (n->list) {
    emit_icmptype_argument_list(n->list);
    printf(" ");
  }
  emit_icmptype_argument(n->arg);
}

EMIT(icmptype_specifier) {
  printf("icmptype { ");
  if (n->list)
    emit_icmptype_argument_list(n->list);
  printf(" }");
}

EMIT(protocol_argument) { printf("%s", n->proto); }

EMIT(protocol_argument_list) {
  if (n->list) {
    eprint("emitting protocol_argument_list\n");
    emit_protocol_argument_list(n->list);
    printf(" ");
  }
  eprint("emitting protocol_argument\n");
  emit_protocol_argument(n->arg);
}

EMIT(protocol_specifier) {
  printf("proto { ");
  if (n->list) {
    eprint("emitting protocol_argument\n");
    emit_protocol_argument_list(n->list);
  }
  printf(" }");
}

EMIT(port_argument) {
  if (n->port_min) {
    printf("%s", n->port_min);
  }
  if (n->port_max) {
    printf(":%s", n->port_max);
  }
}

EMIT(port_argument_list) {
  if (n->list) {
    eprint("emitting port_argument_list\n");
    emit_port_argument_list(n->list);
    printf(" ");
  }
  eprint("emitting port_argument\n");
  emit_port_argument(n->arg);
}

EMIT(port_specifier) {
  if (n->type == TOK_DPORT) {
    printf("dport ");
  } else if (n->type == TOK_SPORT) {
    printf("sport ");
  }
  printf("{ ");
  if (n->list)
    emit_port_argument_list(n->list);
  printf(" }");
}

EMIT(host_argument) {
  if (n->host) {
    printf("%s", n->host);
  }
  if (n->mask) {
    printf("/%s", n->mask);
  }
}

EMIT(host_argument_list) {
  if (n->list) {
    emit_host_argument_list(n->list);
    printf(" ");
  }
  emit_host_argument(n->arg);
}

EMIT(host_specifier) {
  if (n->type == TOK_SOURCE) {
    printf("source ");
  } else if (n->type == TOK_DEST) {
    printf("dest ");
  }
  printf("{ ");
  if (n->list)
    emit_host_argument_list(n->list);
  printf(" }");
}

EMIT(target_specifier) {
  switch (n->type) {
  case TOK_ACCEPT:
    printf("accept");
    break;
  case TOK_REJECT:
    printf("reject");
    break;
  case TOK_DROP:
    printf("drop");
    break;
  case TOK_REDIRECT:
    printf("redirect");
    break;
  case TOK_MASQ:
    printf("masq");
    break;
    break;
  default:
    printf("error");
    break;
  }
}

EMIT(direction_argument) {
  eprint("emitting direction\n");
  if (n->direction)
    printf("%s", n->direction);
  else
    printf("error: n->direction is NULL\n");
}

EMIT(direction_argument_list) {
  if (n->list) {
    eprint("emitting direction_argument_list\n");
    emit_direction_argument_list(n->list);
    printf(" ");
  }
  if (n->arg) {
    eprint("emitting direction_argument\n");
    emit_direction_argument(n->arg);
  }
}

EMIT(direction_specifier) {
  if (n->type == TOK_INPUT) {
    printf("input ");
  } else {
    printf("output ");
  }
  printf("{ ");
  if (n->list) {
    eprint("emitting direction_argument\n");
    emit_direction_argument_list(n->list);
  }
  printf(" }");
}

EMIT(specifier) {
  if (n->compound) {
    eprint("emitting compound_specifier\n");
    emit_compound_specifier(n->compound);
  } else if (n->direction) {
    eprint("emitting direction_specifier\n");
    emit_direction_specifier(n->direction);
  } else if (n->target) {
    eprint("emitting target_specifier\n");
    emit_target_specifier(n->target);
  } else if (n->host) {
    eprint("emitting host_specifier\n");
    emit_host_specifier(n->host);
  } else if (n->port) {
    eprint("emitting port_specifier\n");
    emit_port_specifier(n->port);
  } else if (n->protocol) {
    eprint("emitting protocol_specifier\n");
    emit_protocol_specifier(n->protocol);
  } else if (n->icmptype) {
    eprint("emitting icmptype_specifier\n");
    emit_icmptype_specifier(n->icmptype);
  } else if (n->option) {
    eprint("emitting routing_specifier\n");
    emit_option_specifier(n->option);
  } else {
    eprint("emitting chaingroup_specifier\n");
    emit_chaingroup_specifier(n->chaingroup);
  }
}

EMIT(negated_specifier) {
  if (n->negated) {
    printf("! ");
  }
  eprint("emitting specifier\n");
  emit_specifier(n->spec);
}

EMIT(specifier_list) {
  if (n->list) {
    eprint("emitting specifier_list\n");
    emit_specifier_list(n->list);
    /* specifiers are separated by spaces */
    printf(" ");
  }
  eprint("emitting negated_specifier\n");
  emit_negated_specifier(n->spec);
}

EMIT(rule) {
  if (n->list) {
    eprint("emitting specifier_list\n");
    emit_specifier_list(n->list);
  }
  /* rules end in a semicolon and newline */
  printf(";\n");
}

EMIT(rule_list) {
  if (n->list) {
    eprint("emitting rule_list\n");
    emit_rule_list(n->list);
  }
  if (n->rule) {
    eprint("emitting rule\n");
    emit_rule(n->rule);
  }
}

EMIT(ast) {
  if (n->list) {
    eprint("emitting rule_list\n");
    emit_rule_list(n->list);
  }
}

int main(int argc __attribute__((unused)),
         char **argv __attribute__((unused))) {
  char *EMITTRACE;
  struct ast_s ast;
  int res;

  EMITTRACE = getenv("EMITTRACE");
  emittrace = EMITTRACE ? atoi(EMITTRACE) : 0;

  res = yyparse((void *)&ast);

  if (res != 0) {
    printf("yyparse returned %d\n", res);
    return 1;
  }

  eprint("emitting ast\n");
  emit_ast(&ast);

  return 0;
}