[gnu.g++.bug] gnulib3.cc

jjc@relay.eu.net (James Clark) (11/27/89)

It occurred to me that if gnulib3.c were written in C++ rather than C,
then the xyzzy stuff that's currently in builtin.cc could be put in
gnulib3.cc. This means that those who don't want to install all of
libg++ can use a minimal libg++.a which just contains gnulib3.o. It
also allows __main to be a little prettier.

Here's some diffs to the Makefile:

*** Makefile.dist	Mon Nov 27 12:40:46 1989
--- Makefile	Mon Nov 27 13:20:36 1989
***************
*** 204,212 ****
  
  # gnulib is not a target because a proper installation of GNU CC
  # will place it where g++ can find it.  Same with cpp
! all: crt1+.o g++ cc1plus ld++ g++filt # collect crt0+.o
  # On COFF systems, use the target below.
! # all: g++ cc1plus collect # crt0+.o crt1+.o
  
  doc: $(srcdir)/cpp.info $(srcdir)/g++.info
  
--- 204,212 ----
  
  # gnulib is not a target because a proper installation of GNU CC
  # will place it where g++ can find it.  Same with cpp
! all: crt1+.o g++ cc1plus ld++ g++filt gnulib3.o # collect crt0+.o
  # On COFF systems, use the target below.
! # all: g++ cc1plus collect gnulib3.o # crt0+.o crt1+.o
  
  doc: $(srcdir)/cpp.info $(srcdir)/g++.info
  
***************
*** 322,327 ****
--- 322,330 ----
  crt1+.o: crt1.c config.h
  	$(CRT1_COMMAND)
  	mv crt1.o crt1+.o
+ 
+ gnulib3.o: gnulib3.cc g++ cc1plus
+ 	./g++ -B./ -O -c $(COFFLAGS) $<
  
  cc1plus: $(CPLUS_OBJS) $(OBJS) $(LIBDEPS) lastfile.o
  	$(CC) $(CFLAGS) $(LDFLAGS) -o cc1plus lastfile.o $(CPLUS_OBJS) $(OBJS) $(LIBS)

Here's gnulib3.cc:

#if defined(sun)
#define ON_EXIT on_exit
#endif

#ifndef USE_COLLECT

struct __xyzzy__
{
  __xyzzy__ () {}
  ~__xyzzy__ () {}
};

static __xyzzy__ __1xyzzy__;

#endif

struct set_vector
{
  int length;
  int vector[1];
};

extern set_vector __CTOR_LIST__;
extern set_vector __DTOR_LIST__;

static set_vector *__dlp;
static int __dli;

static void
__do_global_init ()
{
  typedef void (*ctor_t)();
  register ctor_t *ppf = (ctor_t *)__CTOR_LIST__.vector;
  int len = __CTOR_LIST__.length;

  for (int i = 0; i < len; i++)
    (*ppf[i])();
}


static void
__do_global_cleanup ()
{
  typedef void (*dtor_t)();

  while (__dlp)
    {
      while (--__dli >= 0)
	{
	  dtor_t pf = dtor_t(__dlp->vector[__dli]);
	  (*pf)();
	}
      __dlp = (struct set_vector *)__dlp->vector[__dlp->length];
      if (__dlp) __dli = __dlp->length;
    }
}

extern "C" {

int
__main ()
{
#ifdef ON_EXIT
  extern void ON_EXIT(void*, void*);
  ON_EXIT (__do_global_cleanup, 0);
#endif

  __dli = __DTOR_LIST__.length;
  __dlp = &__DTOR_LIST__;
  __do_global_init ();
}

#ifndef ON_EXIT
void 
exit (int status)
{
  extern void _cleanup ();
  extern void _exit (int);

  __do_global_cleanup ();
  _cleanup ();
  _exit (status);
}
#endif

}

James Clark
jjc@jclark.uucp