#include "args.h"
#include "config.h"
/*
 * Copyright (c) 1986, 2014 by The Trustees of Columbia University in
 * the City of New York.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  + Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *  + Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 *  + Neither the name of Columbia University nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 */

#ifndef lint
static const char *rcsid = "$Header: /usr/local/src/mm/mm-0.94/mm/RCS/mkversion.c,v 1.1 2005/05/28 22:27:52 beebe Exp $";
#endif

/*
 * mkversion:
 * create a version string for MM
 */

#include "args.h"
#include "config.h"
#include "osfiles.h"
#include "compat.h"
#include "mm-patchlevel.h"

#define PROGNAME "Columbia MM"		/* program name */

#ifndef MM_MAJOR
#define MM_MAJOR 0
#endif
#ifndef MM_MINOR
#define MM_MINOR 0
#endif
#ifndef MM_PATCH
#define MM_PATCH 0
#endif
#ifndef MM_EDIT
#define MM_EDIT 0
#endif

int maj = MM_MAJOR, min = MM_MINOR, pat = MM_PATCH, edit = MM_EDIT;

static void usage ARGS((void));

FILE *mm_popen ARGS((const char *command, const char *type));
int main ARGS((int argc, char **argv));
int mm_pclose ARGS((FILE *stream));
void scanversion ARGS((void));

extern char *ctad ARGS((time_t it));
extern char *getlocalhostname ARGS((void));
extern char *whoami ARGS((void));

int
#if HAVE_STDC
main (int argc, char **argv)
#else /* K&R style */
main (argc, argv)
int argc;
char **argv;
#endif /* HAVE_STDC */
{
    FILE *fp;
    char *user, *host;
    int fn = 0;

    if (argc > 2)
	usage ();

    scanversion ();

    if (argc == 2) {
	if (argv[1][0] == '-' || argv[1][0] == '+')
	    ++argv[1];
	switch (argv[1][0]) {
	  case 'e':
	  case 'm':
	  case 'M':
	    fn = argv[1][0];
	    if (argv[1][1] == 0)
		break;
	  default:
	    usage ();
	}
    }

    switch (fn) {
      case 'M':
	maj++;
	min = edit = 0;
	break;
      case 'm':
	min++;
	edit = 0;
	break;
      case 'e':
	edit++;
	break;
    }

    printf ("Updating version.h for %s %d.%d.%d(%d)\n",
	    PROGNAME, maj, min, pat, edit);

    fp = fopen ("version.h", "w");
    if (!fp) {
	perror ("mkversion: fopen: version.h");
	exit (1);
    }

    fprintf (fp, "/*\n * %s\n */\n\n",
	     "This file is automatically generated by \"mkversion\"");

    fprintf (fp, "#include \"mm-patchlevel.h\"\n");
    fprintf (fp, "#define MM_MAJOR %d\n", maj);
    fprintf (fp, "#define MM_MINOR %d\n", min);
    fprintf (fp, "#define MM_EDIT %d\n", edit);
    fprintf (fp, "#define MM_VERSION \"%s, version %d.%d.%d(%d)\"\n",
	     PROGNAME, maj, min, pat, edit);

    user = whoami ();
    host = getlocalhostname ();

    fprintf (fp, "#define MM_COMPILED \"");
    if (user) {
	if (host)
	    fprintf (fp, "by %s@%s ", user, host);
	else
	    fprintf (fp, "by %s ", user);
    }
    fprintf (fp, "on %s\"\n", ctad ((time_t) 0));

    if (fclose (fp) == EOF) {
	perror ("mkversion: fclose");
	exit (1);
    }

    exit (0);
}

static void
#if HAVE_STDC
usage (void)
#else /* K&R style */
usage (VOID)
#endif /* HAVE_STDC */
{
    fprintf (stderr, "usage: mkversion [ e | m | M ]\n");
    exit (1);
}

void
#if HAVE_STDC
scanversion (void)
#else /* K&R style */
scanversion (VOID)
#endif /* HAVE_STDC */
{
    int n;
    char line[512];
    FILE *fp;

    fp = fopen ("version.h", "r");
    if (fp) {
	while (fgets (line, sizeof line, fp) == line) {
	    if (sscanf (line, "#define MM_MAJOR %d", &n) == 1)
		maj = n;
	    else if (sscanf (line, "#define MM_MINOR %d", &n) == 1)
		min = n;
	    else if (sscanf (line, "#define MM_EDIT %d", &n) == 1)
		edit = n;
	}
	fclose (fp);
    }
}

/*
 * stubs for MM's fancy popen routines
 */

FILE *
#if HAVE_STDC
mm_popen (const char *command, const char *type)
#else /* K&R style */
mm_popen (command, type)
const char *command, *type;
#endif /* HAVE_STDC */
{
    return (popen(command, type));
}

int
#if HAVE_STDC
mm_pclose (FILE *stream)
#else /* K&R style */
mm_pclose (stream)
FILE *stream;
#endif /* HAVE_STDC */
{
    return(pclose (stream));
}
