/* Copyright (C) 1993,1994 by the author(s).
 
 This software is published in the hope that it will be useful, but
 WITHOUT ANY WARRANTY for any part of this software to work correctly
 or as described in the manuals. See the ShapeTools Public License
 for details.

 Permission is granted to use, copy, modify, or distribute any part of
 this software but only under the conditions described in the ShapeTools 
 Public License. A copy of this license is supposed to have been given
 to you along with ShapeTools in a file named LICENSE. Among other
 things, this copyright notice and the Public License must be
 preserved on all copies.
*/
/*
 * ShapeTools/shape program - std.c
 *
 * Author: Axel Mahler (Axel.Mahler@cs.tu-berlin.de) and Wolfgang Obst
 *
 * $Header: std.c[8.0] Mon Dec 20 19:52:39 1993 axel@cs.tu-berlin.de frozen $
 */
#ifndef lint
static char *AtFSid = "$Header: std.c[8.0] Mon Dec 20 19:52:39 1993 axel@cs.tu-berlin.de frozen $";
#endif

/* reearrangement of suffixes ??? */
/* implicit predefined rules with more than one target ??? */

#include "shape.h"

#define STDRULETABSIZE 64
#define MAXIMPLICIT STDRULETABSIZE

EXPORT struct rules *stdruletab[STDRULETABSIZE];
EXPORT int lastrule;

/* char *stdsuff = ".o .c .c~ .mod .mod~ .sym .def .def~ .p .p~ .f .f~ .F .F~ .r .r~ .y .y~ .l .l~ .s .s~ .sh .sh~ .h .h~ "; */

/* .x~ suffixes are not supported */

EXPORT char *stdsuff = ".o .c .mod .sym .def .a .p .f .F .r .y .l .s .sh .h";

EXPORT char *shaperules = "%.o:%.c %.o:%.l %.o:%.y %.o:%.s %.o:%.r %.o:%.F %.o:%.f %.o:%.mod %.o:%.p %.c:%.l %.c:%.y %.sym:%.def %.a:%.c %:%.sh %:%.r %:%.F %:%.f %:%.p %:%.mod %:%.c ";

EXPORT int implicit_suffs[MAXIMPLICIT] = {19, /* 19   .c       */ 
					   18, /* 18   .mod     */ 
					   17, /* 17   .p       */ 
					   16, /* 16   .f       */ 
					   15, /* 15   .F       */ 
					   14, /* 14   .r       */ 
					   13, /* 13   .sh      */ 
					   0, /* 12   .c.a     */ 
					   9, /* 11   .def.sym */ 
					   2, /* 10   .y.c     */ 
					   1, /*  9   .l.c     */ 
					   11, /*  8   .p.o     */ 
					   10, /*  7   .mod.o   */ 
					   8, /*  6   .f.o     */ 
					   7, /*  5   .F.o     */ 
					   6, /*  4   .r.o     */ 
					   5, /*  3   .s.o     */ 
					   4, /*  2   .y.o     */ 
					   3, /*  1   .l.o     */ 
					   12, /*  0   .c.o     */ 
					   -1 };


LOCAL char *stdrules[] = {

/* ".c.a",
"\t$(CC) -c $(CFLAGS) $(vflags) $<",
"\tar rv $@ $*.o",
"\trm -f $*.o", */

  "%.a",  /* 0 */
  "%.c",
  "+(CC)",
  "+(CFLAGS)",
  "+(vflags)",
  "\t@echo shape - executing: $(CC) -c $(CFLAGS) $#;",
  "\t@$(CC) $(CFLAGS) -E %.c | sed 's;^\\(# [0-9][0-9]* \"\\)%.c\\(\".*\\)$$;\\1$#\\2;' > %.i;",
  "\t@$(CC) -c $(CFLAGS) %.i;",
  "\t@rm %.i;",
  "\tar rv %.a %.o",
  "\trm -f %.o",

/* ".l.c",
"\t$(LEX) $(LFLAGS) $<",
"\tmv lex.yy.c $@", */

  "%.c",  /* 1 */
  "%.l",
  "+(LEX)",
  "+(LFLAGS)",
  "\t$(LEX) $(LFLAGS) %.l",
  "\tmv lex.yy.c %.c",

/* ".y.c",
"\t$(YACC) $(YFLAGS) $<",
"\tmv y.tab.c $@", */

  "%.c",  /* 2 */
  "%.y",
  "+(YACC)",
  "+(YFLAGS)",
  "\t$(YACC) $(YFLAGS) %.y",
  "\tmv y.tab.c %.c",

/* ".l.o",
"\t$(LEX) $(LFLAGS) $<",
"\t$(CC) $(CFLAGS) $(vflags) -c lex.yy.c",
"\trm lex.yy.c",
"\tmv lex.yy.o $@", */

  "%.o",  /* 3 */
  "%.l",
  "+(LEX)",
  "+(LFLAGS)",
  "+(CC)",
  "+(CFLAGS)",
  "+(vflags)",
  "\t@echo shape - executing: $(LEX) $(LFLAGS) $#;",
  "\t@$(LEX) $(LFLAGS) %.l",
  "\t@$(CC) $(CFLAGS) -E lex.yy.c | sed 's;^\\(# [0-9][0-9]* \"\\)%.l\\(\".*\\)$$;\\1$#\\2;' > lex.yy.i;",
  "\t@echo shape - executing: $(CC) $(CFLAGS) $(vflags) -c lex.yy.c",
  "\t@$(CC) $(CFLAGS) $(vflags) -c lex.yy.i",
  "\trm lex.yy.c",
  "\t@rm lex.yy.i",
  "\tmv lex.yy.o %.o",

/* ".y.o",
"\t$(YACC) $(YFLAGS) $<",
"\t$(CC) $(CFLAGS) $(vflags) -c y.tab.c",
"\trm y.tab.c",
"\tmv y.tab.o $@", */

  "%.o",  /* 4 */
  "%.y",
  "+(YACC)",
  "+(YFLAGS)",
  "+(CC)",
  "+(CFLAGS)",
  "+(vflags)",
  "\t@echo shape - executing: $(YACC) $(YFLAGS) $#;",
  "\t@$(YACC) $(YFLAGS) %.y",
  "\t@$(CC) $(CFLAGS) -E y.tab.c | sed 's;^\\(# [0-9][0-9]* \"\\)%.y\\(\".*\\)$$;\\1$#\\2;' > y.tab.i;",
  "\t@echo shape - executing: $(CC) $(CFLAGS) $(vflags) -c y.tab.c",
  "\t@$(CC) $(CFLAGS) $(vflags) -c y.tab.i",
  "\trm y.tab.c",
  "\t@rm y.tab.i",
  "\tmv y.tab.o %.o",

/* ".s.o",
"\t$(AS) $(ASFLAGS) -o $@ $<", */

  "%.o",  /* 5 */
  "%.s",
  "+(AS)",
  "+(ASFLAGS)",
  "\t$(AS) $(ASFLAGS) -o %.o %.s",

/* ".r.o",
"\t$(FC) $(RFLAGS) $(FFLAGS) -c $<", */

  "%.o",  /* 6 */
  "%.r",
  "+(FC)",
  "+(RFLAGS)",
  "+(FFLAGS)",
  "\t$(FC) $(RFLAGS) $(FFLAGS) -c %.r",

/* ".F.o",
"\t$(FC) $(FFLAGS) -c $<", */

  "%.o",  /* 7 */
  "%.F",
  "+(FC)",
  "+(FFLAGS)",
  "\t$(FC) $(FFLAGS) -c %.F",

/* ".f.o",
"\t$(FC) $(FFLAGS) -c $<", */

  "%.o",  /* 8 * */
  "%.f",
  "+(FC)",
  "+(FFLAGS)",
  "\t$(FC) $(FFLAGS) -c %.f",

/* ".def.sym",
"\t$(M2C) $(M2FLAGS) $<", */

  "%.sym",  /* 9 */
  "%.def",
  "+(M2C)",
  "+(M2FLAGS)",
  "\t$(M2C) $(M2FLAGS) %.def",

/* ".mod.o",
"\t$(M2C) $(M2FLAGS) $<", */

  "%.o",  /* 10 */
  "%.mod",
  "+(M2C)",
  "+(M2FLAGS)",
  "\t$(M2C) $(M2FLAGS) %.mod",

/* ".p.o",
"\t$(PC) $(PFLAGS) -c $<", */

  "%.o",  /* 11 */
  "%.p",
  "+(PC)",
  "+(PFLAGS)",
  "\t$(PC) $(PFLAGS) -c %.p",

#ifdef NOVGDB
/* ".c.o",
"\t$(CC) $(CFLAGS) $(vflags) -c $<", */

  "%.o",  /* 12 */
  "%.c",
  "+(CC)",
  "+(CFLAGS)",
  "+(vflags)",
  "\t@echo shape - executing: $(CC) -c $(CFLAGS) %.c;",
  "\t@$(CC) -c $(CFLAGS) %.c;",
  "\t@rm %.i;",
#else /* NOVGDB */
/* ".c.o",
"\t$(CC) $(CFLAGS) $(vflags) -c $<", */

  "%.o",  /* 12 */
  "%.c",
  "+(CC)",
  "+(CFLAGS)",
  "+(vflags)",
  "\t@echo shape - executing: $(CC) -c $(CFLAGS) $#;",
  "\t@$(CC) $(CFLAGS) -E %.c | sed 's;^\\(# [0-9][0-9]* \"\\)%.c\\(\".*\\)$$;\\1$#\\2;' > %.i;",
  "\t@$(CC) -c $(CFLAGS) %.i;",
  "\t@rm %.i;",
#endif /* NOVGDB */

/* ".sh",
"\tcat $< >$@; chmod +x $@", */

  "%",  /* 13 */
  "%.sh",
  "\tcat %.sh >%; chmod +x %",

/* ".r",
"\t$(FC) $(RFLAGS) $(FFLAGS) $(LDFLAGS) $< -o $@", */

  "%",  /* 14 */
  "%.r",
  "+(FC)",
  "+(RFLAGS)",
  "+(FFLAGS)",
  "+(LDFLAGS)",
  "\t$(FC) $(RFLAGS) $(FFLAGS) $(LDFLAGS) %.r -o %",

/* ".F",
"\t$(FC) $(FFLAGS) $(LDFLAGS) $< -o $@", */

  "%",  /* 15 */
  "%.F",
  "+(FC)",
  "+(FFLAGS)",
  "+(LDFLAGS)",
  "\t$(FC) $(FFLAGS) $(LDFLAGS) %.F -o %",

/* ".f",
"\t$(FC) $(FFLAGS) $(LDFLAGS) $< -o $@", */

  "%",  /* 16 */
  "%.f",
  "+(FC)",
  "+(FFLAGS)",
  "+(LDFLAGS)",
  "\t$(FC) $(FFLAGS) $(LDFLAGS) %.f -o %",

/* ".p",
"\t$(PC) $(PFLAGS) $(LDFLAGS) $< -o $@", */

  "%",  /* 17 */
  "%.p",
  "+(PC)",
  "+(PFLAGS)",
  "+(LDFLAGS)",
  "\t$(PC) $(PFLAGS) $(LDFLAGS) %.p -o %",

/* ".mod",
"\t$(M2C) $(M2FLAGS) $(LDFLAGS) $< -e $@ -o $@", */

  "%",  /* 18 */
  "%.mod",
  "+(M2C)",
  "+(M2FLAGS)",
  "+(LDFLAGS)",
  "\t$(M2C) $(M2FLAGS) $(LDFLAGS) %.mod -e % -o %",

/* ".c",
"\t$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@", */

  "%",  /* 19 */
  "%.c",
  "+(CC)",
  "+(CFLAGS)",
  "+(LDFLAGS)",
  "\t@echo shape - executing: $(CC) $(CFLAGS) $# -o %;",
  "\t@$(CC) $(CFLAGS) -E %.c | sed 's;^\\(# [0-9][0-9]* \"\\)%.c\\(\".*\\)$$;\\1$#\\2;' > %.i;",
  "\t@$(CC) $(CFLAGS) $(LDFLAGS) %.i -o %;",
  "\t@rm %.i;",

/* ".SUFFIXES:",
".o",".c",".c~",".mod",".mod~",".sym",".def",".def~",".p",".p~",".f",".f~",".F",".F~",".r",".r~",".y",".y~",".l",".l~",".s",".s~",".sh",".sh~",".h",".h~",
*/

"0"

};

LOCAL struct cmds *newcmds()
{
  register struct cmds *reval;
  
  reval = (struct cmds *) malloc(sizeof (struct cmds));
  if (!reval)
    errexit(10,"malloc");
  reval->nextcmd = (struct cmds *) 0;
  reval->command = (char *)0;
  return reval;
}

EXPORT void add_stdrules()
{
  register int i = 0, j = 0, k = 0;
  register struct cmds *comm;

  while(strcmp(stdrules[i],"0") != 0)
      {
	if (is_pattern (stdrules[i]))
	  {
	    if((stdruletab[k] = 
		(struct rules *) malloc( sizeof(struct rules))) == 
	       (struct rules *) NIL)
	      errexit(10,"malloc");
	    memset ((char *)stdruletab[k], 0, sizeof (struct rules));
	    stdruletab[k]->name = stdrules[i];
	    stdruletab[k]->next = (struct rules *)NIL;
	    i++;
	  }
	if(stdrules[i][0] != '\t')
	  {
	    while ((stdrules[i][0] != '\t') &&
		   (stdrules[i][0] != '+') &&
		   (strcmp(stdrules[i],"0") != 0))
	      {
		stdruletab[k]->deplist = stdrules[i];
		stdruletab[k]->firstdep = stdrules[i];
		i++;
	      }
	  }
	if (stdrules[i][0] == '+')
	  {
	    j = 0;
	    while (stdrules[i][0] == '+')
	      {
		stdruletab[k]->heritage[j] = stdrules[i];
		i++;
		j++;
	      }
	    stdruletab[k]->heritage[j] = NIL;
	  }
	else
	  stdruletab[k]->heritage[0] = NIL;

	if (stdrules[i][0] == '\t')
	  {
	    comm = stdruletab[k]->cmdlist = newcmds();
	    if (stdrules[i][0] == '\t')
	      do
		{
		comm->command = stdrules[i];
		comm->nextcmd = newcmds();
 		comm = comm->nextcmd;
		i++;
	      }  while (stdrules[i][0] == '\t');

	    stdruletab[k]->targetlist[0] = stdruletab[k]->name;
	    stdruletab[k]->targetlist[1] = NIL;
	  }
	k++;
      }
  stdruletab[k] = (struct rules *) NIL;
  lastrule = k - 1;
}
