/*-----------------------------------------------------------------------*
   mycpp.c - main program, my C macro pre-processor
   Copyright (C) 2003 Robert Maul

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.
   
   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

   $Log: mycpp.c,v $
   Revision 1.2  2003/01/24 22:53:44  maulr
   *** empty log message ***

   Revision 1.1.1.1  2003/01/24 22:19:05  maulr


 *-----------------------------------------------------------------------*/

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

#include "data.h"

FILE *fout, *fin;
char *outfilename;
char *infilename;
char *progname;

node_p top; /* top of stack (see: data.c) */
node_p cur; /* current statement ptr */
node_p root; /* root of statement list */

extern char *base_name (char const *name);
extern char *arg(char *s, int n, char delim);
extern void data_line(char *buf, int line_count, char *filename);

/*-----------------------------------------------------------------------*
 - function: usage
 *-----------------------------------------------------------------------*/

usage() {
  fprintf(stderr, "usage %s [-i infile] [-o outfile] [-v]\n", progname);
  fprintf(stderr, "note: stdin and stdout assumed if I/O not specified\n");
  exit(1);
}

/*-----------------------------------------------------------------------*
 - function: arguments
 *-----------------------------------------------------------------------*/

arguments(int argc, char **argv) {
  int arg;
  int invalid;

  arg = 1;
  invalid = 0;
  do { 
    if (argv[arg][0] == '-') {
      if (strcmp(argv[arg], "-i") == 0) {
        if (++arg>argc) usage();
          infilename = argv[arg];
        } else if (strcmp(argv[arg], "-o") == 0) {
           if (++arg>argc) usage();
             outfilename = argv[arg];
	} else if (strcmp(argv[arg], "-v") == 0) {
	  printf("MyCPP Version 1.0\n");
          exit(0);
        } else invalid++;
      } else invalid++;
      if (invalid) {
         printf("invalid option '%s'\n", argv[arg]);
         usage();
      }
      arg++;
  } while (arg<argc);
}

/*-----------------------------------------------------------------------*
 - function: files
 *-----------------------------------------------------------------------*/

files() {
  if (outfilename) {
    fout = fopen(outfilename, "w");
    if (fout == NULL) {
      fprintf(stderr,"%s: cannot open %s\n", progname, outfilename);
      exit(1);
    }
  } else {
    fout = stdout;
  }
  if (infilename) {
    fin = fopen(infilename,"r");
    if (fin == NULL) {
      fprintf(stderr, "%s: cannot open %s\n", progname, infilename);
      exit(1);
    }
  } else {
    fin = stdin;
    infilename = "standard input";
  }
}

/*-----------------------------------------------------------------------*
 - function: init
 *-----------------------------------------------------------------------*/

init() {
  files();
  cur = root = make_node(STATEMENT, 0, 0, 0, 0);
  top = make_node(STACK, cur, cur, cur, 0);
}

/*-----------------------------------------------------------------------*
 - function: clear
 *-----------------------------------------------------------------------*/

clear(char *buf, int buflen) {
  int i;
  for (i=0; i<buflen; i++)
    buf[i] = '\0';
}

/*-----------------------------------------------------------------------*
 - function: main
 *-----------------------------------------------------------------------*/

main(int argc, char **argv) {

  int c, ll, line_count, buflen;
  char *buf;

  line_count = ll = 0;
  buflen = BUFLEN;
  buf = (char *) malloc(buflen+1);
  progname = base_name(argv[0]);
  if (argc>1) {
    arguments(argc, argv);
  }
  init();
  while ((c = getc(fin)) != EOF) {
    if (ll >= buflen) {
      buflen += BUFINC;
      buf = (char *) realloc(buf, buflen+1);
    }      
    buf[ll++] = c;
    if (c == '\n') {
      buf[ll-1] = '\0'; /* change newline char to NULL char */
      line_count++;
      ll = 0;
      data_line(buf, line_count, infilename);
      clear(buf, buflen);
    }
  }
}
 
