/* This file is part of the origami distribution (Amiga Port)
 *
 * Source code written by Thomas in December 1991
 * Version : 1.6.42 alpha, June 1992
 * mkref 1.0
 * (C)1992 by Thomas Hadig
 */
#define version "1.0"

/*{{{  debug*/
/* define this symbol like
 * #define DEBUG_V(a) a
 * and you will get a lot more debug information in verbose mode
 * Lots of fun ! :-)
 */
#define DEBUG_V(a) a
/*}}}  */
/*{{{  includes*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <local/bool.h>
#include <local/argparse.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
/*}}}  */
/*{{{  variables*/
#define IS_READABLE 4
#define PATH_SEP "/"

FILE *fp,*fd;

#define MAX 256

char wkdir[MAX],line[MAX];
int curr_dir_len = 0;
char *line_ptr=NULL;
long posi;

/*{{{  got*/
int got=0,got_lines=0;
long got_seekpos;
char *got_file,*got_string;
/*}}}  */
/*{{{  argparse*/
bool typedefs=FALSE,structures=FALSE,files=FALSE,prototypes=FALSE,
     modules=FALSE,defines=FALSE,norefs=FALSE,all=FALSE,variables=FALSE,
     usage=FALSE,refs=TRUE,quiet=FALSE,verbose=FALSE,c_source=FALSE,
     pragmas=FALSE;
char filename[MAX]="T:mkref.ref";
int recurs=-1;

/*{{{  argument parser table*/
#define argnum 16

ARG argtab[] =
{
  't', BOOL_ARG,   &typedefs,
  's', BOOL_ARG,   &structures,
  'f', BOOL_ARG,   &files,
  'p', BOOL_ARG,   &prototypes,
  'm', BOOL_ARG,   &modules,
  'd', BOOL_ARG,   &defines,
  'n', BOOL_ARG,   &norefs,
  'a', BOOL_ARG,   &all,
  'w', BOOL_ARG,   &variables,
  'r', INT_ARG,    &recurs,
  'o', STRING_ARG, filename,
  'q', BOOL_ARG,   &quiet,
  'v', BOOL_ARG,   &verbose,
  'g', BOOL_ARG,   &pragmas,
  'h', BOOL_ARG,   &usage,
  '?', BOOL_ARG,   &usage
};
/*}}}  */
/*}}}  */
/*}}}  */

/*{{{  Check file or dir existence*/
/*{{{  exist*/
int exist (char *ptr, struct stat *st)

 {
  if (stat (ptr,st)) return 0;            /* error */
  return 1;
 }
/*}}}  */
/*{{{  exist_dir*/
int exist_dir (char *ptr)

 {
  struct stat st;

  if (exist(ptr,&st))
    if (st.st_mode&S_IFDIR) return 1;
  return 0;
 }
/*}}}  */
/*}}}  */

/*{{{  getting lines and args*/
/*{{{  end*/
char *end (char *to,int i,char *from)
{
  to[i++]=0;
  if (*from)
  /*{{{  not last character in line*/
  {
    to[i]=0;
    return from;
  }
  /*}}}  */
  /*{{{  last character in line*/
  to[i]=1;
  return NULL;
  /*}}}  */
}
/*}}}  */
/*{{{  get_line*/
int get_line (char *buf,int len)

{
  *buf =0;
  while (!*buf)
  {
    posi=ftell (fd);
    if (feof (fd)) return 1;
    fgets (buf,len,fd);
    if (got) got_lines++;
    if (buf[strlen(buf)-1]=='\n') buf[strlen(buf)-1]=0;
    while ((*buf)&&(isspace(buf[strlen(buf)-1])))
      buf[strlen(buf)-1]=0;
  }
  if (verbose) fprintf (fp,"Got new line :%s\n",buf);
  return 0;
}
/*}}}  */
#define BREAK_CHAR "\"\'\\,;[]{}()/*= \t"
/*{{{  get_arg*/
char *get_arg (char *to)
{
  /* returns NULL on end of file, returns first arg on normal termination
   * to contains string 0 end, end = 1 for end_of_line following
   */
  char *ptr;

  if (!line_ptr)
  /*{{{  get_line*/
  {
    if (get_line (line,MAX))
    {
      to[0]=0;
      return NULL;
    }
    line_ptr=line;
    /*{{{  skip spaces*/
    while (isspace(*line_ptr)) line_ptr++;
    /*}}}  */
  }
  /*}}}  */
  /*{{{  get next arg*/
  /*{{{  is next char break character*/
  if (strchr (BREAK_CHAR,*line_ptr))
  {
    /*{{{  comment handling*/
    /*{{{  comment begin*/
    if (*line_ptr=='/')
    {
      to[0]='/';
      if (*(line_ptr+1)=='*')
      /*{{{  is comment*/
      {
        to[1]='*';
        line_ptr = end (to,2,line_ptr+2);
      }
      else line_ptr = end (to,1,line_ptr+1);
      /*}}}  */
    }
    /*}}}  */
    /*{{{  comment end*/
    else if (*line_ptr=='*')
    {
      to[0]='*';
      if (*(line_ptr+1)=='/')
      /*{{{  is comment*/
      {
        to[1]='/';
        line_ptr = end (to,2,line_ptr+2);
      }
      /*}}}  */
      else line_ptr = end (to,1,line_ptr+1);
    }
    /*}}}  */
    /*}}}  */
    /*{{{  backslash command*/
    else if (*line_ptr=='\\')
    {
      to[0]='\\';
      to[1]=line_ptr[1];
      if ((!to[1])||(isspace(to[1]))) line_ptr=end(to,1,line_ptr+1);
      else line_ptr=end(to,2,line_ptr+2);
    }
    /*}}}  */
    /*{{{  other break chars*/
    else
    {
      to[0]=*line_ptr;
      line_ptr = end (to,1,line_ptr+1);
    }
    /*}}}  */
  }
  /*}}}  */
  /*{{{  scan till next break character*/
  else if (!(ptr = strpbrk(line_ptr,BREAK_CHAR)))
  /*{{{  copy rest of string*/
  {
    strcpy (to,line_ptr);
    to[strlen(to)+1]=1;
    line_ptr=NULL;
  }
  /*}}}  */
  else
  /*{{{  copy till next break_char*/
  {
    int i=0;

    while (line_ptr!=ptr)
    {
      to[i++]=*(line_ptr++);
    }
    line_ptr = end (to,i,line_ptr);
  }
  /*}}}  */
  /*}}}  */
  /*}}}  */
  /*{{{  skip spaces*/
  if (line_ptr) while (isspace(*line_ptr)) line_ptr++;
  /*}}}  */
  DEBUG_V (if (verbose) fprintf (fp,"Got argument %s\n",to);)
  return to;
}
/*}}}  */
/*}}}  */

/*{{{  skip to some point functions*/
/*{{{  get_quote_end*/
void get_quote_end(char quote)
{
  char d[MAX];
  bool stop=FALSE;

  while (!stop)
  {
    if (!get_arg(d)) stop=TRUE;
    else if (*d==quote) stop=TRUE;
  }
}
/*}}}  */
/*{{{  get_end_of_line*/
void get_end_of_line (void)
{
  char b[MAX];
  bool stop = FALSE;

  DEBUG_V (if (verbose) fprintf (fp,"Getting end of line !\n");)
  while (!stop)
  {
    if (!get_arg(b)) stop = TRUE;
    else if (b[strlen(b)+1]==1)
      if ((b[0]!='\\')||(strlen(b)!=1)) stop = TRUE;
  }
  if (verbose) fprintf (fp,"Got end of line !\n");
}
/*}}}  */
void get_comment_end (void);
/*{{{  get_brace_end*/
void get_brace_end (char brace,bool quote)
{
  bool stop=FALSE;
  char c[MAX];

  DEBUG_V(if (verbose) fprintf (fp,"Getting end of brace : %c !\n",brace);)
  while (!stop)
  {
    if (!get_arg (c)) stop=TRUE;
    if (strlen(c)==1)
    /*{{{  one char (brace ?)*/
    {
      /*{{{  end brace found*/
      if (*c==brace) stop=TRUE;
      /*}}}  */
      /*{{{  begin brace, or quote ?*/
      switch (*c)
      {
        /*{{{  {*/
        case '{':
        {
          get_brace_end ('}',quote);
          break;
        }
        /*}}}  */
        /*{{{  [*/
        case '[':
        {
          get_brace_end (']',quote);
          break;
        }
        /*}}}  */
        /*{{{  )*/
        case '(':
        {
          get_brace_end (')',quote);
          break;
        }
        /*}}}  */
        /*{{{  "*/
        case '"':
        {
          if (quote) get_quote_end('\"');
          break;
        }
        /*}}}  */
        /*{{{  '*/
        case '\'':
        {
          if (quote) get_quote_end('\'');
          break;
        }
        /*}}}  */
      }
      /*}}}  */
    }
    /*}}}  */
    else if (strlen (c)==2)
    /*{{{  two chars (comment ?)*/
    {
      if (!strcmp (c,"/*")) get_comment_end();
    }
    /*}}}  */
  }
  if (verbose) fprintf (fp,"Got end of brace : %c !\n",brace);
}
/*}}}  */
/*{{{  get_comment_end*/
void get_comment_end (void)
{
  bool stop=FALSE;
  char c[MAX];

  DEBUG_V(if (verbose) fprintf (fp,"Getting end of comment !\n");)
  while (!stop)
  {
    if (!get_arg (c)) stop=TRUE;
    else if (!strcmp (c,"*/")) stop=TRUE;
  }
  if (verbose) fprintf (fp,"Got end of comment !\n");
}
/*}}}  */
/*{{{  get_last_break*/
void get_last_break (char *a,char *b,char *break_c)
{
  /* a : last string before break charakter,
   * b : break char found,
   */
  bool stop = FALSE;

  DEBUG_V(if (verbose) fprintf (fp,"Getting last string before break !\n");)
  while ((!stop)&&(get_arg(b)))
  {
    if (strlen (b)==1)
    {
      if (!strcmp (b,"{")) get_brace_end ('}',TRUE);
      else if (!strcmp (b,"/*")) get_comment_end ();
      else if (!strcmp (b,"[")) get_brace_end (']',TRUE);
      else if (!strcmp (b,"\"")) get_quote_end('\"');
      else if (!strcmp (b,"\'")) get_quote_end('\'');
      else if (strchr (break_c,*b)) stop=TRUE;
    }
    else
    {
      strcpy (a,b);
    }
  }
  if (verbose) fprintf (fp,"Got last string before break : %s\n",a);
}
/*}}}  */
/*}}}  */

/*{{{  making references*/
/*{{{  write_ref*/
void write_ref (void)

{
  fprintf (fp,"%-30s %6d %s @@%ld\n",got_string,got_lines,
           got_file,got_seekpos);
  got = 0;
  free (got_file);
  free (got_string);
}
/*}}}  */
/*{{{  isref*/
void isref (char *line,char *name)

{
  char a[MAX],b[MAX],c[MAX],d[MAX],*p;

  /*{{{  test on two /*/
  if (!(p=strchr (line,'/'))) return;
  if (!strchr (p+1,'/')) return;
  /*}}}  */
  /*{{{  test on line*/
  if (sscanf (line," %[^/]/%s %[^/]/%s ",a,b,c,d)!=4)
  {
    if (verbose) fprintf (fp,"Didn't get 4 strings : %s,%s,%s,%s\n",a,b,c,d);
    return;
  }
  DEBUG_V(if (verbose) fprintf (fp,"Got srings !\n");)
  if (strcmp (a,c)) return;
  if (strcmp (b,d)) return;
  /*}}}  */
  /*{{{  write if found reference before*/
  if (got) write_ref();
  /*}}}  */
  /*{{{  mark as found*/
  got = 1;
  got_seekpos = ftell (fd);
  if (b[strlen(b)-1]==')')
    while (b[strlen(b)-1]!='(') b[strlen(b)-1]=0;
  got_string = strdup (b);
  got_file = strdup (name+curr_dir_len);
  got_lines = 1;
  /*}}}  */
}
/*}}}  */
/*}}}  */
#define VAR_END_STRING ",;(=["
/*{{{  write_var*/
void write_var (char *file)
{
  if (variables)
   {
    write_ref();
    got_file = strdup (file+curr_dir_len);
   }
  else free (got_string);
}
/*}}}  */
/*{{{  variable handling*/
/*{{{  get_one_var*/
void get_one_var (char *var,char *break_c,char *file)
{
  char a[MAX],b[MAX];

  got_string = strdup (var);
  switch (*break_c)
  {
    /*{{{  variable : [=,;*/
    case '=':
    case ',':
    case ';':
    case '[':
    /*{{{  [dimension][dimension][...] = initvalue ,|;*/
    {
      a[0]=*break_c;
      while (*a=='[')
      {
        get_brace_end (']',TRUE);
        get_arg(a);
        /*{{{  next char has to be break char*/
        if (strlen(a)!=1)
        {
          if (!quiet) fprintf (fp,"Warning : Error in getting var !");
          return;
        }
        /*}}}  */
      }
      if (*a=='=') get_last_break (a,break_c,",;");
      else strcpy (break_c,a);
      write_var(file);
      break;
    }
    /*}}}  */
    /*}}}  */
    /*{{{  prototype, module (*/
    case '(':
    {
      get_brace_end (')',TRUE);
      get_arg(a);
      if ((a)&&(!strcmp(a,";")))
      /*{{{  prototype*/
      {
        if (prototypes)
        {
          write_ref();
          got_file = strdup (file+curr_dir_len);
        }
        else free (got_string);
      }
      /*}}}  */
      else
      /*{{{  module*/
      {
        /*{{{  skipping non-ansi defines*/
        if (strcmp (a,"{")) get_last_break (a,b,"{");
        /*}}}  */
        get_brace_end ('}',TRUE);
        if (modules)
        {
          write_ref();
          got_file = strdup (file+curr_dir_len);
        }
        else free (got_string);
      }
      /*}}}  */
      break;
    }
    /*}}}  */
  }
}
/*}}}  */
/*{{{  get_vars*/
void get_vars (char *fn)
{
  bool stop = FALSE;
  char a[MAX],b[MAX];

  while (!stop)
  {
    /*{{{  skip * at var beginning*/
    do
    {
      if (!get_arg(a)) stop=TRUE;
    } while ((!stop)&&(!strcmp (a,"*")));
    /*}}}  */
    if (!get_arg(b)) stop=TRUE;
    if ((strlen(b)!=1)||(!strchr (VAR_END_STRING,*b))) stop=TRUE;
    get_one_var (a,b,fn);
    got=1;
    if (*b==';') stop = TRUE;
  }
}
/*}}}  */
/*}}}  */

/*{{{  handle one file (c_source)*/
void handle (char *name)

{
  char a[MAX];

  line_ptr=NULL;
  while (get_arg(a))
  {
    if (verbose) fprintf (fp,"handling argument : >>%s<<..",a);
    /*{{{  /**/
    if (!strcmp (a,"/*"))
    {
      if (verbose) fprintf (fp,"comment !\n");
      get_comment_end ();
    }
    /*}}}  */
    /*{{{  "*/
    else if (!strcmp (a,"\""))
    {
      if (verbose) fprintf (fp,"dubble quotes !\n");
      get_quote_end('\"');
    }
    /*}}}  */
    /*{{{  '*/
    else if (!strcmp (a,"\'"))
    {
      if (verbose) fprintf (fp,"single quotes !\n");
      get_quote_end('\'');
    }
    /*}}}  */
    /*{{{  #define*/
    else if (!strcmp (a,"#define"))
    {
      if (verbose) fprintf (fp,"define !\n");
      if (defines)
      {
        /*{{{  store define*/
        got = 1;
        got_seekpos = posi;
        got_file = strdup (name+curr_dir_len);
        get_arg (a);
        got_string = strdup (a);
        got_lines = 1;
        /*}}}  */
        if (!a[strlen(a)+1]) get_end_of_line ();
        write_ref();
      }
    }
    /*}}}  */
    /*{{{  # define or # pragma*/
    else if (!strcmp (a,"#"))
    {
      if (verbose) fprintf (fp,"hash-command !\n");
      if (get_arg(a))
      {
        /*{{{  define*/
        if (!strcmp (a,"define"))
        {
          if (verbose) fprintf (fp,"define !\n");
          /*{{{  define*/
          if (defines)
          {
            /*{{{  store define*/
            got = 1;
            got_seekpos = posi;
            got_file = strdup (name+curr_dir_len);
            get_arg (a);
            got_string = strdup (a);
            got_lines = 1;
            /*}}}  */
            if (!a[strlen(a)+1]) get_end_of_line ();
            write_ref();
          }
          /*}}}  */
        }
        /*}}}  */
        /*{{{  pragma*/
        else if (!strcmp (a,"pragma"))
        {
          if (verbose) fprintf (fp,"pragma !\n");
          /*{{{  pragma*/
          if (pragmas)
          {
            /*{{{  store pragma*/
            got = 1;
            got_seekpos = posi;
            got_file = strdup (name+curr_dir_len);
            /*{{{  get third command (#pragma libcall Base Function ...)*/
            get_arg (a);
            get_arg (a);
            get_arg (a);
            /*}}}  */
            got_string = strdup (a);
            got_lines = 1;
            /*}}}  */
            if (!a[strlen(a)+1]) get_end_of_line ();
            write_ref();
          }
          /*}}}  */
        }
        /*}}}  */
      }
    }
    /*}}}  */
    /*{{{  #pragma*/
    else if (!strcmp (a,"#pragma"))
    {
      if (verbose) fprintf (fp,"pragma !\n");
      if (pragmas)
      {
        /*{{{  store pragma*/
        got = 1;
        got_seekpos = posi;
        got_file = strdup (name+curr_dir_len);
        /*{{{  get third command (#pragma libcall Base Function ...)*/
        get_arg (a);
        get_arg (a);
        get_arg (a);
        /*}}}  */
        got_string = strdup (a);
        got_lines = 1;
        /*}}}  */
        if (!a[strlen(a)+1]) get_end_of_line ();
        write_ref();
      }
    }
    /*}}}  */
    /*{{{  other hash commands : #include, #pragma : skip*/
    else if (*a=='#')
    {
      if (verbose) fprintf (fp,"hash command : skipping !\n");
      if (!a[strlen(a)+1]) get_end_of_line();
    }
    /*}}}  */
    /*{{{  typedef*/
    else if (!strcmp (a,"typedef"))
    {
      if (verbose) fprintf (fp,"typedef !\n");
      if (typedefs)
      {
        char f[MAX];

        /*{{{  store typedef*/
        got = 1;
        got_seekpos = posi;
        got_file = strdup (name+curr_dir_len);
        got_lines = 1;
        /*}}}  */
        /*{{{  skip to semicolon, remember last arg*/
        get_last_break (a,f,";");
        got_string = strdup (a);
        /*}}}  */
        write_ref();
      }
    }
    /*}}}  */
    /*{{{  prototypes, modules, variables, structures*/
    else
    {
      char b[MAX];

      if (verbose) fprintf (fp,"var,mod,pro,str !\n");
      /*{{{  store define*/
      got = 1;
      got_seekpos = posi;
      got_file = strdup (name+curr_dir_len);
      got_lines = 1;
      /*}}}  */
      if (!strcmp (a,"struct"))
      {
        /*{{{  struct ....*/
        get_arg(b);
        get_arg(a);
        if (!strcmp (a,"{"))
        /*{{{  get end of struct def*/
        {
          get_brace_end ('}',TRUE);
          /*{{{  write struct ref*/
          if (structures)
          {
            got_string = strdup (b);
            write_ref();
            got=1;
            got_file = strdup (name+curr_dir_len);
          }
          /*}}}  */
          get_arg(a);
          /*{{{  struct .. {} name vars*/

          if (strcmp (a,";"))
          {
            get_arg (b);
            get_one_var (a,b,name);
            if (*b==',')
            {
              got=1;
              get_vars(name);
            }
          }
          /*}}}  */
        }
        /*}}}  */
        else
        /*{{{  struct name vars*/
        {
          get_arg (b);
          get_one_var (a,b,name);
          if (*b==',')
          {
            got=1;
            get_vars (name);
          }
        }
        /*}}}  */
        /*}}}  */
      }
      else
      {
        /*{{{  variable, module, prototype def*/
        bool stop=FALSE;

        while (!stop)
        {
          if (!get_arg(a)) stop=TRUE;
          if ((strlen(a)==1)&&(strchr (VAR_END_STRING,*a)))
          /*{{{  end of first def found*/
          {
            get_one_var (b,a,name);
            if (*a==',')
            {
              got=1;
              get_vars (name);
            }
            stop=TRUE;
          }
          /*}}}  */
          else if (strncmp (a,"__",2)) strcpy (b,a);
          /* this strncmp handles name __ARGS((blubb)) */
        }
        /*}}}  */
      }
    }
    /*}}}  */
  }
}
/*}}}  */
/*{{{  parse_file*/
void parse_file (char *file)

{
  char line[MAX];

  /*{{{  verbose*/
  if (verbose) fprintf (fp,"parsing file %s\n",file);
  /*}}}  */
  /*{{{  open file*/
  if (!(fd = fopen (file,"r")))
  {
    if (!quiet) fprintf (fp,"Warning : Can't open file >>%s<<\n",file);
    return;
  }
  /*}}}  */
  /*{{{  references*/
  if (refs)
  {
    while (!feof (fd))
    /*{{{  handle one line*/
    {
      if (!get_line (line,MAX))
      {
        if (verbose) fprintf (fp,"handling line : >>%s<<\n",line);
        isref (line,file);
      }
    }
    /*}}}  */
    if (got) write_ref();
    if (c_source) rewind (fd);
  }
  /*}}}  */
  got=0;
  /*{{{  c-source*/
  if (c_source) handle (file);
  /*}}}  */
  /*{{{  file*/
  if (files)
  {
    char *ptr;

    /*{{{  mark as found*/
    got = 1;
    got_seekpos = 0;
    line_ptr=file;
    while (ptr = strchr (line_ptr,'/')) line_ptr=ptr+1;
    got_string = strdup (line_ptr);
    got_file = strdup (file+curr_dir_len);
    got_lines = 0;
    /*}}}  */
    /*{{{  count lines*/
    rewind (fd);
    while (!get_line(line,MAX));
    /*}}}  */
    write_ref();
  }
  /*}}}  */
  /*{{{  close file*/
  fclose (fd);
  /*}}}  */
}
/*}}}  */
/*{{{  parse_dir*/
void parse_dir (char *dir, int recurs, int rec)

{
  char name[MAX];
  DIR *dfd;
  struct direct *d;
  struct stat st;

  /*{{{  verbose*/
  if (verbose) fprintf (fp,"Handling dir %s\n",dir);
  /*}}}  */
  if (!(dfd=opendir (dir)))
  /*{{{  error*/
  {
    if (!quiet) fprintf (fp,"Can't open directory >>%s<<\n",dir);
  }
  /*}}}  */
  else
  {
    /*{{{  handle whole directory*/
    while (d=readdir (dfd))
    /*{{{  handle file or directory*/
    {
      strcpy (name,dir);
      if (name[strlen(name)-1]!=':')
        strncat (name,PATH_SEP,MAX-strlen(name));
      strncat (name,d->d_name,MAX-strlen(name));
      if (exist (name,&st))
      {
      /*{{{  handle file*/
      if (st.st_mode & S_IFREG)
      {
        parse_file (name);
      }
      /*}}}  */
      /*{{{  handle dir*/
      else if (st.st_mode & S_IFDIR)
       {
        bool stop=TRUE;

        if (rec==0) stop=FALSE;
        if (rec>0) if (recurs>1) stop=FALSE;
        if (!stop)
        /*{{{  recursiv search through directories*/
        {
          parse_dir (name,recurs-1,rec);
        }
        /*}}}  */
        else
        /*{{{  end of recursiv*/
        {
          if (verbose)
          {
            if (rec>0) fprintf (fp,"Max depth reached for %s\n",d->d_name);
            else fprintf (fp,"Directory %s will not be handled !\n",d->d_name);
          }
        }
        /*}}}  */
       }
      /*}}}  */
      /*{{{  error*/
      else
        if (!quiet) fprintf (fp,"Unknown File Type >>%s<<\n Type : %d\n",
                             name,st.st_mode);
      /*}}}  */
      }
    }
    /*}}}  */
    /*}}}  */
    closedir (dfd);
  }
}
/*}}}  */

/*{{{  main*/
void main (int argc, char **argv)

 {
  struct stat st;

  argc=argparse(argc,argv,argtab,argnum);
  /*{{{  usage*/
  if ((usage)||(argc>2))
  {
    fprintf (stderr,"mkref Version %s\nUsage : %s\t%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
           version,
           argv[0],"(c)1992 by Thomas Hadig"
           "-t (enable typdefs)      -s (enable structures)",
           "-f (enable files)        -p (enable prototypes)",
           "-m (enable modules)      -d (enable defines)",
           "-w (enable variables)    -a (enable all)",
           "-n (disable references)  -?,-h (help)",
           "-q (quiet)               -v (verbose)",
           "-g (pragmas)",
           "-o filename (write to filename instead T:mkref.ref)",
           "-r [depth] (search recursivly [to depth])");
    exit (0);
  }
  /*}}}  */
  /*{{{  current dir or argument*/
  if (argc!=2)
  {
    getcwd (wkdir,MAX);
    curr_dir_len = strlen (wkdir)+1;
  }
  else strcpy (wkdir,argv[1]);
  /*}}}  */
  /*{{{  all*/
  if (all)
  {
    typedefs=structures=files=prototypes=modules=defines=variables=TRUE;
    pragmas=TRUE;
  }
  /*}}}  */
  /*{{{  norefs*/
  if (norefs) refs = FALSE;
  /*}}}  */
  /*{{{  something to do ?*/
  if ((!refs)&&(!typedefs)&&(!structures)&&(!files)&&(!prototypes)&&
      (!modules)&&(!defines)&&(!variables))
  {
    fprintf (stderr,"Nothing to do !\n");
    exit (0);
  }
  /*}}}  */
  /*{{{  c-source*/
  if ((typedefs)||(structures)||(prototypes)||(modules)||(pragmas)||
      (defines)||(variables))
  {
    c_source=TRUE;
  }
  /*}}}  */
  /*{{{  open file*/
  if (!(fp=fopen (filename,"w")))
  {
    if (!quiet) fprintf (stderr,"Error : Can't open file >>%s<<\n",filename);
    exit (1);
  }
  /*}}}  */
  /*{{{  verbose*/
  if (verbose)
  {
    quiet = FALSE;
    fprintf (fp,"enabled :\n");
    if (typedefs) fprintf (fp,"typedefs,\n");
    if (structures) fprintf (fp,"structures,\n");
    if (files) fprintf (fp,"files,\n");
    if (prototypes) fprintf (fp,"prototypes,\n");
    if (modules) fprintf (fp,"modules,\n");
    if (defines) fprintf (fp,"defines,\n");
    if (variables) fprintf (fp,"variables,\n");
    if (pragmas) fprintf (fp,"pragmas,\n");
    if (refs) fprintf (fp,"references\n");
    fprintf (fp,"end enables !\n");
  }
  /*}}}  */
  /*{{{  start handling*/
  /*{{{  handle dir*/
  if (exist_dir(wkdir))
    parse_dir (wkdir,recurs,recurs);
  /*}}}  */
  /*{{{  handle file*/
  else
  {
    if (exist (wkdir,&st))
      parse_file (wkdir);
  /*}}}  */
  /*{{{  error*/
    else if (!quiet) fprintf (fp,"File >>%s<< does not exist !\n",wkdir);
  }
  /*}}}  */
  /*}}}  */
 }
/*}}}  */
