#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <ctype.h>
#include <dir.h>

/*
 * Simple tool for generating dependencies from .c/.h files.
 * COMPILE WITH DJGPP ONLY.
 *
 * Notes: This isn't a C-preprocessor, so it doesn't handle "#include"
 * files inside comments or "#if" blocks. Output dependencies are always
 * written in lower case.
 */

char  include[]  = "#include";
char  exclude[]  = "@NO_DEP";
char *obj_prefix = "";
char *obj_suffix = ".$(O)";

int usage (const char *who_am_i)
{
  fprintf (stderr, "syntax: %s [-v] [-p obj-prefix] [-s obj-suffix] "
           ".c/.h-files | @resp\n", who_am_i);
  return (-1);
}

int main (int argc, char **argv)
{
  int   ch, idx;
  int   num_files = 0;
  int   num_includes = 0;
  int   num_deps = 0;
  int   verbose = 0;
  char *prog = argv[0];
  char *fname;

  while ((ch = getopt(argc,argv,"vp:s:")) != EOF)
     switch (ch)
     {
       case 'v': verbose = 1;
                 break;
       case 'p': obj_prefix = optarg;
                 break;
       case 's': obj_suffix = optarg;
                 break;
       case '?':
       default:  return usage (prog);
     }

  argc -= optind;
  argv += optind;

  if (argc < 1)
     return usage (prog);

  printf ("#\n# Generated by %s. DO NOT EDIT\n#\n", prog);

  for (idx = 0; idx < argc && (fname = argv[idx]) != NULL; idx++)
  {
    char  buf[512], drive[3], dir[256], stem[256], ext[5];
    int   c_file, h_file;
    int   rvalue;
    FILE *fin;


    fin = fopen (fname, "rt");
    if (!fin)
    {
      fprintf (stderr, "Cannot read `%s'\n", fname);
      return (-1);
    }

    drive[0] = dir[0] = stem[0] = ext[0] = '\0';
    fnsplit (fname, drive, dir, stem, ext);
    strlwr (stem);
    strlwr (ext);

    if (verbose)
       fprintf (stderr, "Processing `%s%s%s'\n", dir, stem, ext);

    if (!ext[0])
    {
      fprintf (stderr, "`%s' is not a .c or .h-file\n", fname);
      continue;
    }

    c_file = (stricmp(ext,".c") == 0);
    h_file = (stricmp(ext,".h") == 0);

    if (!c_file && !h_file)
    {
      fprintf (stderr, "`%s' is not a .c or .h-file\n", fname);
      continue;
    }

    rvalue = 0;
    num_deps = 0;

    while (fgets(buf,sizeof(buf),fin))
    {
      char *cp, *cp1 = buf;

      while (isspace(*cp1))
            cp1++;

      if (*cp1 != '#' || ++cp1 == '\0')
         continue;

      while (isspace(*cp1))
            cp1++;

      if (!*cp1 ||
          strnicmp(cp1,"include",7) ||
          (cp = strchr(cp1,'\"')) == NULL)
         continue;

      cp++;
      if (!*cp || (cp1 = strchr(cp, '\"')) == NULL)   /* find right '"' */
         continue;

      /* Only accept .c/.h files
       */
      if (cp1[-2] != '.' || (cp1[-1] != 'c' && cp1[-1] != 'h'))
         continue;

      if (strstr(cp,exclude))
      {
        if (verbose)
           fprintf (stderr, "Excluding line %s\n", buf);
        continue;
      }

      num_includes++;
      num_deps++;

      if (!rvalue)  /* processing left side of dependency */
      {
        strlwr (fname);
        if (c_file)
             printf ("%s%s%s: %s", obj_prefix, stem, obj_suffix, fname);
        else printf ("%s:", fname);
        rvalue = 1;
      }

      /* now print the right side */
      *cp1 = '\0';
      if (dir[0] && c_file)
           printf (" %s%s", dir, cp);
      else printf (" %s", cp);
    }
    if (rvalue)
       putchar ('\n');
    fclose (fin);

    num_files++;
    if (verbose && num_deps > 0)
       fprintf (stderr, "  %d dependant(s)\n", num_deps);
  }

  if (verbose)
     fprintf (stderr, "Processed %d files with %d include files\n",
              num_files, num_includes);

  return (num_files > 0 ? 0 : 1);
}

