/*
** genauto.c
**
** Creates C source with INIT/EXIT functions for automatic opening
** and closing of libraries.
**
** V0.3  20-Oct-98  phx
**       Library version may be defined by the user. For example:
**         unsigned long _XyzBaseVer = 99;
**       otherwise, a version of 0 will be used.
**       A second argument is allowed to define the priority of the
**       INIT/EXIT functions.
** V0.2  07-Oct-98  vb
**       _INIT, _EXIT, no printf (requires vlink 0.5f)
** V0.1  06-Oct-98  phx
**       created
**
*/

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#define VERSION 0
#define REVISION 3
#define BUFSIZE 256
#define DEFPRI 5  /* default priority for INIT/EXIT functions */


main(int argc,char *argv[])
{
  char linebuf[BUFSIZE];
  char namebuf[BUFSIZE];
  char *p,*q,*base = NULL;
  FILE *f;
  int n;
  int pri = DEFPRI;

  if (argc<2 || argc>3) {
    printf("genauto V%d.%d\nusage: %s <FD file> [<defpri>]\n",
           VERSION,REVISION,argv[0]);
    exit(1);
  }
  if (argc==3)
    pri = atoi(argv[2]);  /* override default priority */

  if (f = fopen(argv[1],"r")) {

    /* determine library name from FD file name */
    /* Example: FD:graphics_lib.fd  -->  graphics.library */
    n = strlen(argv[1]);
    p = argv[1]+(n-1);
    q = namebuf;
    while (n--) {
      if (*p=='/' || *p==':')
        break;
      p--;
    }
    p++;
    while (isalnum((unsigned)*p))
      *q++ = *p++;
    strcpy(q,".library");

    /* get base name from FD file */
    while (fgets(linebuf,BUFSIZE-1,f)) {
      if (!strncmp(linebuf,"##base",6)) {
        p = linebuf+6;
        while (*p && *p!='_')
          p++;
        if (*p) {
          base = ++p;
          while (isgraph((unsigned)*p))
            p++;
          strcpy(p,".c");
        }
        break;
      }
    }
    fclose(f);
    if (!base) {
      fprintf(stderr,"No valid base definition found in %s\n",argv[1]);
      exit(10);
    }

    /* generate C source */
    if (f = fopen(base,"w")) {
      *p = 0;  /* remove ".c" from base */

      fprintf(f,"#include <exec/libraries.h>\n"
                "#include <proto/exec.h>\n\n"
                "struct Library *%s = NULL;\n"
                "extern unsigned long _%sVer;\n\n"
                "void _INIT_%d_%s()\n{\n"
                "  if (!(%s = OpenLibrary(\"%s\",_%sVer)))\n"
                "    exit(20);\n}\n\n"
                "void _EXIT_%d_%s()\n{\n"
                "  if (%s)\n    CloseLibrary(%s);\n}\n",
                base,base,pri,base,base,namebuf,base,pri,base,base,base);
      fclose(f);
    }
    else {
      fprintf(stderr,"Can't create main source file %s\n",base);
      exit(10);
    }

    /* a second source for the library version */
    sprintf(namebuf,"%sVer.c",base);
    if (f = fopen(namebuf,"w")) {
      fprintf(f,"unsigned long _%sVer = 0;\n",base);
      fclose(f);
    }
    else {
      fprintf(stderr,"Can't create version source file %s\n",namebuf);
      exit(10);
    }
  }

  else {
    fprintf(stderr,"Can't read FD file: %s\n",argv[1]);
    exit(10);
  }
  exit(0);
}
